转置嵌套生成器

哈哈4t0

有没有一种清晰的方法可以遍历列表中每个生成器的项目?我认为证明问题实质的最简单方法就是证明一个例子。这里是

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(如该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)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章