我定义了一个生成器,从Elasticsearch中产生日志条目:
def gen():
....
for hit in results:
yield hit
我该如何同时循环遍历两个元素?类似以下代码实现:
for one, two in gen():
...
所谓两个元素指的是:A,B
,B,C
,...,Y,Z
(对于生成的列表A,B,...,Y,Z
)。
此答案假设您想要非重叠的一对。您可以通过使用zip()
来实现,因为迭代器会被消耗:
for one, two in zip(gen, gen):
# do something
示例:
>>> gen = (x for x in range(5))
>>> for one, two in zip(gen, gen): print(one,two)
...
0 1
2 3
注意,正如timgeb所评论的那样,如果你的元素数量不均匀并且你想要最后一个带有填充值的元素,则应使用itertools.zip_longest
,例如:
>>> gen = (x for x in range(5))
>>> for one, two in zip_longest(gen, gen): print(one, two)
...
0 1
2 3
4 None
itertools.tee
来构建第二个迭代器,将第二个迭代器推进一次并丢弃结果,然后使用 zip
在成对的情况下循环遍历两个迭代器。>>> from itertools import tee
>>> it = iter('abc')
>>> it1, it2 = tee(it)
>>>
>>> next(it2, None)
'a'
>>> for first, second in zip(it1, it2):
... first, second
...
('a', 'b')
('b', 'c')
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
izip
,特别是如果您的迭代器/生成器可以生成无限数量的对象。 - timgebiter
来调用,像这样:it1, it2 = iter(my_list), iter(my_list)
。 - juanpa.arrivillagadef gen():
results = [1, 2, 3, 4, 5]
for i, v in enumerate(results):
# if i < len()
if (i + 1) < len(results):
yield (v, results[i + 1])
else:
yield v
output = gen()
for each in output:
print(each)
输出将会是:
(1, 2)
(2, 3)
(3, 4)
(4, 5)
5
itertools.izip_longest
将会得到(last_element, None)
(或任何您想要的填充值)。 - timgebzip_longest
(假设是 Python 3)。 - Chris_Rands