Я пытался реализовать обратную функцию 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 использует последнее значение, поэтому генераторы не сохраняют значение, пока они создаются внутри первого генератора.
Я что-то упускаю и не знаю, что это такое.
Заранее спасибо, если что-то прояснит мне эту ситуацию.
UPDATE:
Я нашел объяснение здесь PEP-289 , мое первое чтение было на PEP-255.
Решение, которое я пытаюсь реализовать, является ленивым, поэтому:
zip(*iter) or izip(*...)
не работает для меня, потому что * arg расширяет список аргументов.