2010-10-05 3 views
14

Alle Diskussion geht um Python 3.1.2; für die Quelle meiner Frage siehe Python docs.Verständnis Zip-Funktion

Ich weiß, was zip tut; Ich verstehe einfach nicht, warum kann es wie folgt umgesetzt werden:

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

Sagen wir, ich zip(c1, c2, c3) nennen. Wenn ich richtig verstehe, ist iterables zunächst das Tupel (c1, c2, c3).

Die Zeile iterables = map(iter, iterables) konvertiert es in einen Iterator, der iter (c1), iter (c2), iter (c3) zurückgibt, wenn iteriert wird.

Innerhalb der Schleife map(next, iterables) ist ein Iterator, der durch next(iter(c1)), next(iter(c2)) und next(iter(c3)) wenn iteriert zurückkehren würde. Der tuple Anruf konvertiert es zu (next(iter(c1)), next(iter(c2)), next(iter(c3)), sein Argument (iterables) beim ersten Anruf erschöpfend, soweit ich sagen kann. Ich verstehe nicht, wie die while Schleife weitergeht, da sie iterables überprüft; und wenn es weitergeht, warum der Aufruf tuple kein leeres Tupel zurückgibt (der Iterator ist erschöpft).

Ich bin sicher, ich bin etwas fehlt ganz einfach ..

+0

Seltsam, es endlos Schleifen für mich, auch wenn es ganz gut aussieht ... und mein eigener Versuch funktioniert auch nicht o.O Ich bin schockiert. – delnan

+0

Ich denke, das ist nur Pseudocode und sollte nicht wörtlich genommen werden. –

+1

@Radomir Doporalski Es ist Python-Code, nicht Pseudocode, direkt aus der Dokumentation kopiert. Ich wäre sehr traurig, wenn ich mich nicht darauf verlassen könnte, und stattdessen musste ich mir überlegen, was die Funktion wirklich macht. Ich beziehe mich immer dann auf den Code, wenn ich mir bezüglich der Semantik der Funktion nicht 100% ig sicher bin. – max

Antwort

9

Es sieht aus wie es ein Fehler in der Dokumentation ist. Der "äquivalente" Code funktioniert in python2, aber nicht in python3, wo er in eine Endlosschleife geht.

Und die neueste Version der Dokumentation hat das gleiche Problem: http://docs.python.org/release/3.1.2/library/functions.html

wie Änderung Sieht 61361 das Problem war, da es Änderungen von Python 2.6 verschmolzen, ohne zu überprüfen, dass sie für python3 korrekt waren.

Es sieht so aus, als ob das Problem nicht in der Dokumentationsgruppe für Trunks existiert, aber Sie sollten wahrscheinlich einen Fehler darüber unter http://bugs.python.org/ melden.

+0

Ok, berichtet.Um dies zu verdeutlichen: Die while wird als wahr ausgewertet, weil "iterables" ein Iterator ist; und der Iterator wird unabhängig vom Inhalt immer als wahr ausgewertet. Außerdem werden die "iterablens" beim ersten Lauf durch die Schleife erschöpft, so dass es danach leeres Tupel ergeben würde. Richtig? – max

+0

@max: es wird zu "True" ausgewertet, weil "iterables" eine nicht leere Liste ist. Hast du überhaupt gelesen, was ich gepostet habe? – SilentGhost

+0

Entschuldigen Sie Ihre Antwort :(Also, wenn in Python 2 ausgeführt, wäre es wahr, weil iterables Liste nicht leer ist, aber wenn in Python 3 ausgeführt (was ich in meinem Kommentar angenommen), wäre es wahr, weil iterables ein Iterator ist , und Iterator wertet immer als richtig aus, richtig? – max

7

Es scheint, als ob dieser Code als Python-2.x-Code gelesen werden soll. Es läuft nicht einmal richtig in py3k.

Was passiert in Python-2.x ist, dass map eine Liste von Iteratoren zurückgeben, wenn next aufgerufen wird, gibt es ein Element von Iterator, diese Elemente in Tupel zusammengefasst. So, da

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

Iterables eine Liste der 2-Iteratoren, bei jeder Iteration in der while-Schleife, die nächste (ersten verbleibendes) Element des Iterators verbraucht wird (‘'A' und 'x', usw.), und ergab als Element von einem Tupel, dann nachdem die letzten Elemente ergeben sind, (in der 3. Iteration) ausgelöst StopIteration stoppt den Generator. while iterables bleibt immer True.

+0

+1 für Python-2.x Erklärung. – max

+0

@max es wird getaggt Python-3 sagt, es geht nur um Python 3. Warum upvote auf der Grundlage, dass die Antwort für Python-2 ist? Ditto Ruby, oder irgendetwas anderes, dass nicht Python-3? –

+1

@RobertGrant, weil die Bezugnahme auf Python 2 war die einzige Möglichkeit zu erklären, wie Die offizielle Python-Dokumentation war anscheinend völlig falsch. – max