是否有一种明确的方法来迭代列表中每个生成器的项目?我相信展示问题本质的最简单方法是举一个例子。在这里
0。假设我们有一个返回生成器的函数:
def gen_fun(hint):
for i in range(1,10):
yield "%s %i" % (hint, i)
1。具有直接迭代顺序的清晰解决方案:
hints = ["a", "b", "c"]
for hint in hints:
for txt in gen_fun(hint):
print(txt)
这会打印
a 1
a 2
a 3
...
b 1
b 2
b 3
...
2。具有反向迭代顺序的麻烦解决方案
hints = ["a", "b", "c"]
generators = list(map(gen_fun, hints))
any = True
while any:
any = False
for g in generators:
try:
print(next(g))
any = True
except StopIteration:
pass
这会打印
a 1
b 1
c 1
a 2
b 2
...
这按预期工作并且达到了我想要的效果。
奖励积分:
相同的任务,但 gen_fun
范围可能不同,即
def gen_fun(hint):
if hint == 'a':
m = 5
else:
m = 10
for i in range(1,m):
yield "%s %i" % (hint, i)
本例的正确输出是:
a 1
b 1
c 1
a 2
b 2
c 2
a 3
b 3
c 3
a 4
b 4
c 4
b 5
c 5
b 6
c 6
b 7
c 7
b 8
c 8
b 9
c 9
问题:
有没有办法实现情况2清理器?
最佳答案
如果我正确理解了这个问题,您可以使用 zip()
来实现与整个 while any
循环相同的效果:
hints = ["a", "b", "c"]
generators = list(map(gen_fun, hints))
for x in zip(*generators):
for txt in x:
print(txt)
输出:
a 1
b 1
c 1
a 2
b 2
...
更新:
如果生成器的长度不同,请将它们全部“压缩”到最短。您可以使用itertools.izip_longest (如 this q/a 建议)以实现相反的行为并继续屈服,直到最长的生成器耗尽。不过,您需要过滤掉填充的值:
hints = ["a", "b", "c"]
generators = list(map(gen_fun, hints))
for x in zip_longest(*generators):
for txt in x:
if txt:
print(txt)
关于python - 转置嵌套生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33699885/