95

一个如何循环通过一个生成器?我是这样想的:

gen = function_that_returns_a_generator(param1, param2)
if gen: # in case the generator is null
    while True:
        try:
            print gen.next()
        except StopIteration:
            break

有没有更蟒蛇的方式?

4

7 回答 7

164

简单地

for x in gen:
    # whatever

会成功的。请注意,if gen总是返回True.

于 2012-07-18T10:24:11.170 回答
17
for item in function_that_returns_a_generator(param1, param2):
    print item

您无需担心测试以查看您的函数是否返回任何内容,就好像没有返回任何内容一样,您将不会进入循环。

于 2012-07-18T10:23:46.660 回答
15

如果您不需要生成器的输出,因为您只关心它的副作用,您可以使用以下单行:

for _ in gen: pass

跟进

根据 aiven 的评论,我进行了一些性能测试,虽然它看起来list(gen)比 略快for _ in gen: pass,但它tuple(gen)甚至更快,所以我的最终建议是使用,以防你只关心副作用

tuple(gen)
于 2015-11-24T10:25:47.930 回答
7

您可以简单地循环遍历它:

>>> gen = (i for i in range(1, 4))
>>> for i in gen: print i
1
2
3

但请注意,您只能循环一次。下次生成器将为空:

>>> for i in gen: print i
>>> 
于 2016-02-01T21:27:35.950 回答
5

其他答案适用于复杂的场景。如果您只是想将项目流式传输到列表中:

x = list(generator)

对于简单的预处理,使用列表推导:

x = [tup[0] for tup in generator]

如果只想执行生成器而不保存结果,可以跳过变量赋值:

# no var assignment b/c we don't need what print() returns
[print(_) for _ in gen]
于 2020-06-06T17:38:24.987 回答
4

只需像对待任何其他可迭代对象一样对待它:

for val in function_that_returns_a_generator(p1, p2):
    print val

请注意,if gen:它将始终为 True,因此这是一个错误的测试

于 2012-07-18T10:24:12.617 回答
2

如果您想手动移动生成器(即手动处理每个循环),那么您可以执行以下操作:

    from pdb import set_trace

    for x in gen:
        set_trace()
        #do whatever you want with x at the command prompt
        #use pdb commands to step through each loop of the generator e.g., >>c #continue   
于 2014-01-16T06:53:24.990 回答