Printing items out of a generator

I am practicing printing out items yielded by a generator function.

This works perfectly fine:

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)

But the following code is yielding:

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)

What I want to print is each item from each list sequentially, exhausted when the shortest list is exhausted. I have it working without a generator, but I am trying to wrap my hands around generators.

I want to print this:

f
hello
1
o
world
2

The first element in each, followed by the second, etc., until the shortest list is exhausted. I want to be able to feed in any number of iterables, hence my use of *args .

NOTE My working, non-generator variant uses itertools:

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

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

I was trying to avoid that, if possible.


You can make your non-generator version work lazily too, just avoid the list() calls and use itertools.chain.from_iterable() :

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

As for your implementation; you yielded the whole zip() result, not individual elements from that. Delegate to the zip() iterator with yield from :

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

This still produces the row tuples from the zip() call; you'd need to loop over each contained tuple too:

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

to chain the tuple contents.

Demo of the latter:

>>> 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

Yielding x yields the entire iterable. You need to yield from x .

yield from x
链接地址: http://www.djcxy.com/p/53478.html

上一篇: 迭代器耗尽后,迭代器执行会挂起

下一篇: 从发生器打印物品