发电机可以多次使用吗?
Can generator be used more than once?
这是我定义了两个生成器的代码:
one_line_gen = (x for x in range(3))
def three_line_gen():
yield 0
yield 1
yield 2
当我执行时:
for x in one_line_gen:
print x
for x in one_line_gen:
print x
结果符合预期:
0
1
2
但是,如果我执行:
for x in three_line_gen():
print x
for x in three_line_gen():
print x
结果是:
0
1
2
0
1
2
为什么?我还以为任何生成器都只能用一次
three_line_gen
不是生成器,它是一个函数。你叫它returns的时候它是一个发电机,每次叫它都是一个全新的。每次你像这样放置括号:
three_line_gen()
这是一个全新的迭代生成器。但是,如果您要先做
mygen = three_line_gen()
并迭代 mygen
两次,第二次将如您所料失败。
因为在一个衬里是Generator
对象而三个衬里是一个function
。
他们本来就是不同的。
这两个很相似。
def three_line_gen_fun():
yield 0
yield 1
yield 2
three_line_gen = three_line_gen_fun()
one_line_gen = (x for x in range(3))
type(three_line_gen) == type(one_line_gen)
不,您不能对生成器进行两次迭代。一旦你迭代了它,一个生成器就会耗尽。你可以用 tee
制作一个生成器的副本:
from itertools import tee
one_line_gen = (x for x in range(3))
gen1, gen2 = tee(one_line_gen)
# or:
# gen1, gen2 = tee(x for x in range(3))
for item in gen1:
print(item)
for item in gen2:
print(item)
其他问题见。
是的,发电机只能使用一次。但是你有两个生成器对象。
# Python 3
def three_line_gen():
yield 0
yield 1
yield 2
iterator = three_line_gen()
print(iterator)
for x in iterator:
print(id(iterator), x)
iterator2 = three_line_gen()
print(iterator2)
for x in iterator2:
print(id(iterator2), x)
结果是:
<generator object three_line_gen at 0x1020401b0>
4328784304 0
4328784304 1
4328784304 2
<generator object three_line_gen at 0x1020401f8>
4328784376 0
4328784376 1
4328784376 2
Why? I thought any generator can be used only once.
因为每次调用 three_line_gen() 都会创建一个新的生成器。
否则,你是正确的,发电机只 运行 前进直到耗尽。
Can generator be used more than once?
是的,如果结果在生成器外部进行缓冲,这是可能的。一种简单的方法是使用 itertools.tee():
>>> from itertools import tee
>>> def three_line_gen():
yield 0
yield 1
yield 2
>>> t1, t2 = tee(three_line_gen())
>>> next(t1)
0
>>> next(t2)
0
>>> list(t1)
[1, 2]
>>> list(t2)
[1, 2]
这是我定义了两个生成器的代码:
one_line_gen = (x for x in range(3))
def three_line_gen():
yield 0
yield 1
yield 2
当我执行时:
for x in one_line_gen:
print x
for x in one_line_gen:
print x
结果符合预期:
0
1
2
但是,如果我执行:
for x in three_line_gen():
print x
for x in three_line_gen():
print x
结果是:
0
1
2
0
1
2
为什么?我还以为任何生成器都只能用一次
three_line_gen
不是生成器,它是一个函数。你叫它returns的时候它是一个发电机,每次叫它都是一个全新的。每次你像这样放置括号:
three_line_gen()
这是一个全新的迭代生成器。但是,如果您要先做
mygen = three_line_gen()
并迭代 mygen
两次,第二次将如您所料失败。
因为在一个衬里是Generator
对象而三个衬里是一个function
。
他们本来就是不同的。
这两个很相似。
def three_line_gen_fun():
yield 0
yield 1
yield 2
three_line_gen = three_line_gen_fun()
one_line_gen = (x for x in range(3))
type(three_line_gen) == type(one_line_gen)
不,您不能对生成器进行两次迭代。一旦你迭代了它,一个生成器就会耗尽。你可以用 tee
制作一个生成器的副本:
from itertools import tee
one_line_gen = (x for x in range(3))
gen1, gen2 = tee(one_line_gen)
# or:
# gen1, gen2 = tee(x for x in range(3))
for item in gen1:
print(item)
for item in gen2:
print(item)
其他问题见
是的,发电机只能使用一次。但是你有两个生成器对象。
# Python 3
def three_line_gen():
yield 0
yield 1
yield 2
iterator = three_line_gen()
print(iterator)
for x in iterator:
print(id(iterator), x)
iterator2 = three_line_gen()
print(iterator2)
for x in iterator2:
print(id(iterator2), x)
结果是:
<generator object three_line_gen at 0x1020401b0>
4328784304 0
4328784304 1
4328784304 2
<generator object three_line_gen at 0x1020401f8>
4328784376 0
4328784376 1
4328784376 2
Why? I thought any generator can be used only once.
因为每次调用 three_line_gen() 都会创建一个新的生成器。
否则,你是正确的,发电机只 运行 前进直到耗尽。
Can generator be used more than once?
是的,如果结果在生成器外部进行缓冲,这是可能的。一种简单的方法是使用 itertools.tee():
>>> from itertools import tee
>>> def three_line_gen():
yield 0
yield 1
yield 2
>>> t1, t2 = tee(three_line_gen())
>>> next(t1)
0
>>> next(t2)
0
>>> list(t1)
[1, 2]
>>> list(t2)
[1, 2]