我定义了一个生成器,它从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')
谢谢。这是最干净,最"pythonic"的方法吗?我觉得这个简单问题的解决方案就是复杂。
我认为没有更清洁的解决方案。事实上,这是 itertools 文档中pairwise
配方:
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
我曾经用以下内容解决了类似的问题:
def 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