понимание функции почтового индекса - PullRequest
14 голосов
/ 05 октября 2010

Вся дискуссия о питоне 3.1.2; см. Python docs для получения источника моего вопроса.

Я знаю, что делает zip; Я просто не понимаю, почему это можно реализовать так:

def zip(*iterables):
    # zip('ABCD', 'xy') --> Ax By
    iterables = map(iter, iterables)
    while iterables:
        yield tuple(map(next, iterables))

Допустим, я звоню zip(c1, c2, c3). Если я правильно понимаю, итерации изначально являются кортежем (c1, c2, c3).

Строка iterables = map(iter, iterables) преобразует ее в итератор, который будет возвращать iter (c1), iter (c2), iter (c3), если итерация выполнена.

Внутри цикла, map(next, iterables) - это итератор, который будет возвращать next(iter(c1)), next(iter(c2)) и next(iter(c3)) при повторном выполнении. Вызов tuple преобразует его в (next(iter(c1)), next(iter(c2)), next(iter(c3)), исчерпывая его аргумент (iterables) при самом первом вызове, насколько я могу судить. Я не понимаю, как цикл while удается продолжить, учитывая, что он проверяет iterables; и если это продолжается, почему вызов tuple не возвращает пустой кортеж (итератор исчерпан).

Я уверен, что мне не хватает чего-то очень простого ..

Ответы [ 2 ]

9 голосов
/ 05 октября 2010

Похоже, это ошибка в документации.«Эквивалентный» код работает в python2, но не в python3, где он входит в бесконечный цикл.

И последняя версия документации имеет ту же проблему: http://docs.python.org/release/3.1.2/library/functions.html

Похожеизменение 61361 было проблемой, так как оно объединяло изменения из python 2.6 без проверки того, что они были правильными для python3.вы, вероятно, должны сообщить об ошибке на http://bugs.python.org/.

7 голосов
/ 05 октября 2010

Кажется, что этот код должен читаться как код python-2.x.Он даже не работает должным образом в py3k.

В python-2.x происходит то, что map возвращает список итераторов, когда вызывается next, он возвращает элемент итератора, эти элементыобъединены в кортежИтак, учитывая, что

>>> zip('ABCD', 'xy')

iterables представляет собой список из 2 итераторов, на каждой итерации в цикле while используется следующий (первый оставшийся) элемент итератора (''A' и 'x' и т. Д.)и передается как элемент кортежа, затем после выдачи последних элементов (на 3-й итерации) повышение StopIteration останавливает генератор.while iterables всегда остается True.

...