如何通过发电机循环


80

一个人如何循环通过发电机?我是这样想的:

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

还有更pythonic的方式吗?


我建议使用break; 不是continue
乔恩·克莱门茨

实际上,在生成器可能在元素上引发异常但您不想停止迭代的情况下,我实际上会这样做。
2013年

Answers:


144

只是

for x in gen:
    # whatever

会成功的 请注意,if gen始终返回True


6
不,if gen并不总是返回True。如果op的function_that_returns_a_generator()return None,则在语句中gen求值为。Falseif
drevicko 2013年

44
@drevicko:我假设function_that_returns_a_generator()返回一个生成器(大胆的假设,对吗?)。 None不是发电机。
Sven Marnach

由于OP要求采用“ pythonic方式”,因此,鉴于Python倡导EAFP,这个答案似乎很合法;-)
DerMike

17
for item in function_that_returns_a_generator(param1, param2):
    print item

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


9

如果您只关心生成器的副作用而不需要生成器的输出,则可以使用以下一种格式:

for _ in gen: pass

3
或者只是list(gen)
aiven

6

您可以简单地遍历它:

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

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

>>> for i in gen: print i
>>> 

4

就像对待其他可迭代对象一样对待它:

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

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


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   

1
从pdb import set_trace#no():)
Vlad

1

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

x = list(generator)

(或者,如果您只想触发生成器执行操作,只需 list(generator)

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

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

或当您想执行简单功能时:

# didn't assign to variable b/c we don't care about what the print() function returns
[print(x) for x in gen]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.