迭代列表中的每两个元素

我如何做一个循环或列表理解,使每一次迭代给我两个元素?

 l = [1,2,3,4,5,6] for i,k in ???: print str(i), '+', str(k), '=', str(i+k) 

输出:

 1+2=3 3+4=7 5+6=11 

你需要一个pairwise() (或者grouped() )实现。

对于Python 2:

 from itertools import izip def pairwise(iterable): "s -> (s0, s1), (s2, s3), (s4, s5), ..." a = iter(iterable) return izip(a, a) for x, y in pairwise(l): print "%d + %d = %d" % (x, y, x + y) 

或者更一般地说:

 from itertools import izip def grouped(iterable, n): "s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ..." return izip(*[iter(iterable)]*n) for x, y in grouped(l, 2): print "%d + %d = %d" % (x, y, x + y) 

在Python 3中,可以使用内置的zip()函数replaceizip ,并删除import

所有信贷martineau 他回答 我的问题 ,我发现这是非常有效的,因为它只是在列表上迭代一次,并不会在过程中创build任何不必要的列表。

注意 :这不应该与Python自己的itertools文档中的pairwise配方混淆,如@lazyr所指出的那样,这会产生s -> (s0, s1), (s1, s2), (s2, s3), ...在评论中。

那么你需要2个元素的元组,所以

 data = [1,2,3,4,5,6] for i,k in zip(data[0::2], data[1::2]): print str(i), '+', str(k), '=', str(i+k) 

哪里:

  • data[0::2]表示创build元素的子集合(index % 2 == 0)
  • zip(x,y)从x和y集合中创build相同索引元素的元组集合。
 >>> l = [1,2,3,4,5,6] >>> zip(l,l[1:]) [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)] >>> zip(l,l[1:])[::2] [(1, 2), (3, 4), (5, 6)] >>> [a+b for a,b in zip(l,l[1:])[::2]] [3, 7, 11] >>> ["%d + %d = %d" % (a,b,a+b) for a,b in zip(l,l[1:])[::2]] ['1 + 2 = 3', '3 + 4 = 7', '5 + 6 = 11'] 

简单的解决scheme。

 l = [1,2,3,4,5,6]

我在范围内(0,len(l),2):
     str(l [i]),'+',str(l [i + 1]),'=',str(l [i] + l [i + 1])

尽pipe使用zip所有答案都是正确的,但是我发现自己实现这个function会导致更易读的代码:

 def pairwise(it): it = iter(it) while True: yield next(it), next(it) 

it = iter(it)部分确保it实际上是一个迭代器,而不仅仅是一个迭代器。 如果it已经是一个迭代器,这行是一个无操作。

用法:

 for a, b in pairwise([0, 1, 2, 3, 4, 5]): print(a + b) 
 for (i, k) in zip(l[::2], l[1::2]): print i, "+", k, "=", i+k 

zip(*iterable)用每个迭代的下一个元素返回一个元组。

l[::2]返回列表的第一,第三,第五等元素:第一个冒号表示该段从头开始,因为它后面没有数字,第二个冒号只在需要时才需要(在这个例子中是2)。

l[1::2]做同样的事情,但是从列表的第二个元素开始,所以它返回原始列表的第二,第四,第六等元素。

抱歉迟到了,我希望这将是更加优雅的做法。

 a = [1,2,3,4,5,6] zip(a[::2], a[1::2]) [(1, 2), (3, 4), (5, 6)] 

最接近你写的代码:

 l = [1,2,3,4,5,6] for i,k in zip(l[::2], l[1::2]): print(str(i), '+', str(k), '=', str(i+k)) 

输出:

 1+2=3 3+4=7 5+6=11 

对于任何人可能会有所帮助,这里是解决类似的问题,但重叠对(而不是互斥对)。

从Python的itertools文档 :

 from itertools import izip def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = tee(iterable) next(b, None) return izip(a, b) 

或者更一般地说:

 from itertools import izip def groupwise(iterable, n=2): "s -> (s0,s1,...,sn-1), (s1,s2,...,sn), (s2,s3,...,sn+1), ..." t = tee(iterable, n) for i in range(1, n): for j in range(0, i): next(t[i], None) return izip(*t) 

认为这是一个很好的地方,分享我对n> 2这个概括,这只是一个可迭代的滑动窗口:

 def sliding_window(iterable, n): its = [ itertools.islice(iter, i, None) for i, iter in enumerate(itertools.tee(iterable, n)) ] return itertools.izip(*its) 

在这里我们可以有适合你的for循环的alt_elem方法。

 def alt_elem(list, index=2): for i, elem in enumerate(list, start=1): if not i % index: yield tuple(list[i-index:i]) a = range(10) for index in [2, 3, 4]: print("With index: {0}".format(index)) for i in alt_elem(a, index): print(i) 

输出:

 With index: 2 (0, 1) (2, 3) (4, 5) (6, 7) (8, 9) With index: 3 (0, 1, 2) (3, 4, 5) (6, 7, 8) With index: 4 (0, 1, 2, 3) (4, 5, 6, 7) 

注意:考虑到在func中执行的操作,以上解决scheme可能效率不高。

这个问题的标题是误导性的,你似乎正在寻找连续的对,但是如果你想遍历所有可能的对的集合,这将工作:

 for i,v in enumerate(items[:-1]): for u in items[i+1:]: 

你可以使用more_itertools包。

 import more_itertools lst = range(1, 7) for i, j in more_itertools.chunked(lst, 2): print(f'{i} + {j} = {i+j}')