Вложенные генераторы Python

Я пытался реализовать обратную функцию itertools.izip на Python 2.7.1.Дело в том, что я нахожу проблему, и у меня нет объяснения. Решение 1, iunzip_v1 работает отлично. Но решение 2. iunzip_v2 работает не так, как ожидалось. До сих пор я не нашел никакой соответствующей информации об этой проблеме, и, читая PEP о генераторах, кажется, что он должен работать, но это не так.

import itertools
from operator import itemgetter

def iunzip_v1(iterable):
    _tmp, iterable = itertools.tee(iterable, 2)
    iters = itertools.tee(iterable, len(_tmp.next()))
    return tuple(itertools.imap(itemgetter(i), it) for i, it in enumerate(iters))

def iunzip_v2(iterable):
    _tmp, iterable = itertools.tee(iterable, 2)
    iters = itertools.tee(iterable, len(_tmp.next()))
    return tuple((elem[i] for elem in it) for i, it in enumerate(iters))

результат:

In [17]: l
Out[17]: [(0, 0, 0), (1, 2, 3), (2, 4, 6), (3, 6, 9), (4, 8, 12)]

In [18]: map(list, iunzip.iunzip_v1(l))
Out[18]: [[0, 1, 2, 3, 4], [0, 2, 4, 6, 8], [0, 3, 6, 9, 12]]

In [19]: map(list, iunzip.iunzip_v2(l))
Out[19]: [[0, 3, 6, 9, 12], [0, 3, 6, 9, 12], [0, 3, 6, 9, 12]]

Похоже, что iunzip_v2 использует последнее значение , поэтому генераторы не сохраняют значение, пока они создаются внутри первого генератора. Я чего-то упускаю и не знаю, что именно.

Заранее спасибо, если что-то может прояснить мне эту ситуацию.

ОБНОВЛЕНИЕ: Я нашел объяснение здесь PEP-289 , мое первое чтение было на PEP-255. Решение, которое я пытаюсь реализовать, является ленивым, поэтому:

  zip(*iter) or izip(*...)

не работает для меня, потому что * arg расширяет список аргументов.

7
задан Andrés Moreira 21 June 2011 в 23:41
поделиться