[英]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
. 我希望能够提供任意数量的可迭代对象,因此我使用
*args
。
NOTE My working, non-generator variant uses itertools: 注意我的非发电机工作版本使用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()
: 您也可以让您的非生成器版本也懒洋洋地工作,只需避免调用
list()
并使用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. 您产生了整个
zip()
结果,而不是其中的单个元素。 Delegate to the zip()
iterator with yield from
: 使用
yield from
委托给zip()
迭代器:
def ziplike(*args):
x = zip(*args)
yield from x
This still produces the row tuples from the zip()
call; 这仍然会从
zip()
调用中生成行元组; 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. 产生
x
产生整个可迭代。 You need to yield from x
. 您需要从
x
屈服。
yield from x
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.