Блоки продукта itertools, при использовании генераторов в качестве параметров
Мне нужно построить на выходе декартово произведение, генерируемое двумя или более функциями генератора.
Я бы хотел, чтобы файл itertools.product не блокировался, а вместо этого предоставлял mr первые элементы product, прежде чем функции ввода генератора вызвали StopIteration.
Есть ли функция, которая обеспечивает что-то подобное?
Я написал простую программу, чтобы продемонстрировать мою проблему:
#!/usr/bin/python
import time
import itertools
def g_delay(l, delay):
for i in range(l):
yield i
time.sleep(delay)
def g(l):
for i in range(l):
yield i
if __name__ == "__main__":
start_time = time.time()
p = itertools.product(g_delay(2,1), g_delay(3,1))
elapsed_time = time.time() - start_time
print '%f' % elapsed_time
for i in p:
print i
print
start_time = time.time()
p = itertools.product(g(2), g(3))
elapsed_time = time.time() - start_time
print '%f' % elapsed_time
for i in p:
print i
И вывод:
5.004710
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
0.000017
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
В результате я бы хотел, чтобы первая задержка в 5,004710 секунд была аналогична последней (0,000017), и при доступе к элементам продукта (в цикле for) происходит блокировка.
1 ответ
Решение
Вот версия продукта (всего для двух итераторов), которая пытается быть как можно более ленивой.
def product(i1, i2):
for a in i1:
j2, i2 = itertools.tee(i2)
for b in j2:
yield (a, b)