从发电机打印物品

时间:2017-08-22 17:12:24

标签: python generator

我正在练习打印出由生成器功能产生的项目。

这完全没问题:

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b


sumfib = 0
for i in fibonacci():
    if i >= 4000000:
        break
    elif i % 2 == 0:
        sumfib += i

print(sumfib)

但是下面的代码正在产生:

list1 = ['f', 'o', 'o', 'b', 'a', 'r']
list2 = ['hello', 'world']
list3 = ['1', '2', '3', '4']


def ziplike(*args):
    x = zip(*args)
    yield x


for item in ziplike(list1, list2, list3):
    print(item)

我想要打印的是每个列表中的每个项目顺序,耗尽 当最短列表用尽时。我让它没有一个发电机,但我试图把我的手缠在发电机上。

我想打印一下:

f
hello
1
o
world
2

每个元素中的第一个元素,然后是第二个元素等,直到最短列表用完为止。我希望能够提供任意数量的迭代,因此我使用了*args

注意我的工作,非生成器变体使用itertools:

newlist = list(zip(list1, list2, list3))

temp = list(itertools.chain(*newlist))

如果可能,我试图避免这种情况。

2 个答案:

答案 0 :(得分:2)

您也可以懒惰地使用非生成器版本,只需避免list()次调用并使用itertools.chain.from_iterable()

newlist = zip(list1, list2, list3)
temp = itertools.chain.from_iterable(newlist)

至于你的实施;你得出了整个zip()结果,而不是那个单独的元素。使用zip()

委托yield from迭代器
def ziplike(*args):
    x = zip(*args)
    yield from x

这仍然会产生来自zip()调用的行元组;你也需要遍历每个包含的元组:

def ziplike(*args):
    x = zip(*args)
    for tup in x:
        yield from tup

链接元组内容。

后者的演示:

>>> list1 = ['f', 'o', 'o', 'b', 'a', 'r']
>>> list2 = ['hello', 'world']
>>> list3 = ['1', '2', '3', '4']
>>> def ziplike(*args):
...     x = zip(*args)
...     for tup in x:
...         yield from tup
...
>>> for item in ziplike(list1, list2, list3):
...     print(item)
...
f
hello
1
o
world
2

答案 1 :(得分:0)

屈服x产生整个可迭代。您需要从 x中获得

yield from x