#python #itertools
Вопрос:
У меня есть 3 генератора, как показано ниже
g1 = ((i, i) for i in range(3))
g2 = ((i, i ** 2) for i in range(3))
g3 = ((i, i ** 3) for i in range(3))
Я хочу соединить их вместе (параллельно), чтобы получить вывод типа (i, i, i, i 2, i, i 3). Ниже приведены 2 кода, один работает, а другой нет. Может ли кто-нибудь помочь мне понять, почему второй метод работает не так, как планировалось? Я не совсем до конца понимаю, что делает Python при переносе итераторов.
Вот код, который работает:
from itertools import chain
def combo(iters):
zipped_tuples = zip(*iters)
for zipped_tuple in zipped_tuples:
yield tuple(chain.from_iterable(zipped_tuple))
c = combo((g1, g2, g3))
for item in c:
print(item)
Результат выглядит так, как показано ниже
(0, 0, 0, 0, 0, 0)
(1, 1, 1, 1, 1, 1)
(2, 2, 2, 4, 2, 8)
Вот код, который не работает
from itertools import chain
g1 = ((i, i) for i in range(3))
g2 = ((i, i ** 2) for i in range(3))
g3 = ((i, i ** 3) for i in range(3))
def combo(iters):
zipped_tuples = chain.from_iterable(zip(*iters))
yield from zipped_tuples
c = combo((g1, g2, g3))
for item in c:
print(item)
Вывод осуществляется не параллельно, а последовательно, как показано ниже:
(0, 0)
(0, 0)
(0, 0)
(1, 1)
(1, 1)
(1, 1)
(2, 2)
(2, 4)
(2, 8)
Комментарии:
1. Первый из них каждый раз создает новую цепочку в цикле. Вторая версия просто создает одну цепочку.