Блоки продукта 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)
Другие вопросы по тегам