Некоторые люди скажут вам использовать 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
возвращает тот же объект tee
в качестве первого выходного значения, когдадали tee
объект.Вот почему следует использовать второй генератор.
Это, в сочетании с тем фактом, что doc явно указывает, что list
лучше в этой ситуации, демонстрирует, что первое решение должнобыть предпочтительным:
Этот itertool может потребовать значительного вспомогательного хранения (в зависимости от того, сколько временных данных необходимо сохранить).В общем, если один итератор использует большую часть или все данные до запуска другого итератора, быстрее использовать list()
вместо tee()
.