python3 分叉生成器
python3 bifurcated generator
我正在寻找一个代码来复制生成器,然后继续使用新的生成器。它就像发电机的分叉。
def Generator():
myNumbers=range(3)
for i in myNumbers:
yield i
for i in Generator():
bifurcatedGenerator = Generator
for j in bifurcatedGenerator():
print (i, j)
此代码作为输出给出:
0 0
0 1
0 2
1 0
1 1
1 2 <- wrong
2 0
2 1 <- wrong
2 2 <- wrong
而不同的输出应该是:(分叉生成器需要是一个新实例,但在旧生成器停止的同一点继续。)
0 0
0 1
0 2
1 1
1 2
2 2
应用程序本身要复杂得多,这里只是一个代码示例。
重要的(只对我自己而言)是一个语义优美的解决方案,对第三者来说很好读 parties.Efficiency 不是那么重要
有些人会告诉你使用 itertools.tee
。不要使用 itertools.tee
.
使用 list
要跟踪生成器之前的状态,您需要将之前生成的值存储在 list
中。这就是函数 itertools.tee
在复制生成器时所做的事情。
不幸的是,这消除了使用生成器的所有内存优势。所以你最好使用 list
.
def generator():
yield from range(3)
lst = list(generator())
for i in range(len(lst)):
for j in range(i, len(lst)):
print(lst[i], lst[j])
输出:
0 0
0 1
0 2
1 1
1 2
2 2
那为什么不使用 itertools.tee
?
仍然可以使用 itertools.tee
,但你不应该使用。
from itertools import tee
def generator():
yield from range(3)
lst = list(generator())
main_gen, bif_gen = tee(generator())
for i in main_gen:
for j in bif_gen:
print(i, j)
_, bif_gen = tee(main_gen) # Yes, you *must* use the second item here
前面代码工作的原因很微妙,实际上与以下事实有关:itertools.tee
returns 当给定 [=22= 时,第一个输出值是相同的 tee
对象] 目的。这就是应该使用第二个生成器的原因。
这与 doc 明确指定 list
在这种情况下更好的事实相结合,表明必须首选第一个解决方案:
This itertool may require significant auxiliary storage (depending on
how much temporary data needs to be stored). In general, if one
iterator uses most or all of the data before another iterator starts,
it is faster to use list()
instead of tee()
.
为什么不使用带有启动参数的生成器(并在使用时使用停止参数)?
def Generator(start=0, stop=3):
for i in range(start, stop):
yield i
for i in Generator():
for j in Generator(start=i):
print (i, j)
同时给出输出:
0 0
0 1
0 2
1 1
1 2
2 2
我正在寻找一个代码来复制生成器,然后继续使用新的生成器。它就像发电机的分叉。
def Generator():
myNumbers=range(3)
for i in myNumbers:
yield i
for i in Generator():
bifurcatedGenerator = Generator
for j in bifurcatedGenerator():
print (i, j)
此代码作为输出给出:
0 0
0 1
0 2
1 0
1 1
1 2 <- wrong
2 0
2 1 <- wrong
2 2 <- wrong
而不同的输出应该是:(分叉生成器需要是一个新实例,但在旧生成器停止的同一点继续。)
0 0
0 1
0 2
1 1
1 2
2 2
应用程序本身要复杂得多,这里只是一个代码示例。
重要的(只对我自己而言)是一个语义优美的解决方案,对第三者来说很好读 parties.Efficiency 不是那么重要
有些人会告诉你使用 itertools.tee
。不要使用 itertools.tee
.
使用 list
要跟踪生成器之前的状态,您需要将之前生成的值存储在 list
中。这就是函数 itertools.tee
在复制生成器时所做的事情。
不幸的是,这消除了使用生成器的所有内存优势。所以你最好使用 list
.
def generator():
yield from range(3)
lst = list(generator())
for i in range(len(lst)):
for j in range(i, len(lst)):
print(lst[i], lst[j])
输出:
0 0
0 1
0 2
1 1
1 2
2 2
那为什么不使用 itertools.tee
?
仍然可以使用 itertools.tee
,但你不应该使用。
from itertools import tee
def generator():
yield from range(3)
lst = list(generator())
main_gen, bif_gen = tee(generator())
for i in main_gen:
for j in bif_gen:
print(i, j)
_, bif_gen = tee(main_gen) # Yes, you *must* use the second item here
前面代码工作的原因很微妙,实际上与以下事实有关:itertools.tee
returns 当给定 [=22= 时,第一个输出值是相同的 tee
对象] 目的。这就是应该使用第二个生成器的原因。
这与 doc 明确指定 list
在这种情况下更好的事实相结合,表明必须首选第一个解决方案:
This itertool may require significant auxiliary storage (depending on how much temporary data needs to be stored). In general, if one iterator uses most or all of the data before another iterator starts, it is faster to use
list()
instead oftee()
.
为什么不使用带有启动参数的生成器(并在使用时使用停止参数)?
def Generator(start=0, stop=3):
for i in range(start, stop):
yield i
for i in Generator():
for j in Generator(start=i):
print (i, j)
同时给出输出:
0 0
0 1
0 2
1 1
1 2
2 2