2010-10-05 17 views
14

Todo el debate trata sobre python 3.1.2; ver Python docs para la fuente de mi pregunta.entendiendo la función zip

Sé lo que zip hace; Simplemente no entiendo por qué se puede implementar como esto:

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

Digamos que llamo zip(c1, c2, c3). Si entiendo correctamente, los iterables son inicialmente la tupla (c1, c2, c3).

La línea iterables = map(iter, iterables) la convierte en un iterador que devolvería iter (c1), iter (c2), iter (c3) si se repite.

Dentro del bucle, map(next, iterables) es un iterador que devolvería next(iter(c1)), next(iter(c2)) y next(iter(c3)) si itera a través. La llamada tuple la convierte a (next(iter(c1)), next(iter(c2)), next(iter(c3)), agotando su argumento (iterables) en la primera llamada que yo sepa. No entiendo cómo el circuito while logra continuar dado que comprueba iterables; y si continúa, por qué la llamada tuple no devuelve una tupla vacía (el iterador está agotado).

Estoy seguro de que me falta algo muy simple ..

+0

Extraño, no deja de dar vueltas para mí aunque se vea perfectamente bien ... y mi propio intento tampoco funciona O.O estoy sorprendido. – delnan

+0

Creo que esto es solo pseudocódigo y no debe tomarse literalmente. –

+1

@Radomir Dopieralski Es código Python, no seudocódigo, copiado directamente de la documentación. Sería bastante triste si no pudiera confiar en ello, y en su lugar tuve que hacer mi mejor conjetura acerca de lo que realmente hace la función. Me refiero al código de esta manera cuando no estoy 100% seguro de la semántica de la función. – max

Respuesta

9

Parece que se trata de un error en la documentación. El código 'equivalente' funciona en python2 pero no en python3, donde entra en un bucle infinito.

Y la versión más reciente de la documentación tiene el mismo problema: http://docs.python.org/release/3.1.2/library/functions.html

Parece cambio 61361 era el problema, ya que se fusionó cambios de Python 2.6, sin verificar que eran correctas para python3.

Parece que el problema no existe en el conjunto de documentación de troncales, pero probablemente deba informar un error al respecto al http://bugs.python.org/.

+0

Ok, informado.Para aclarar: el tiempo se evaluará como verdadero porque 'iterables' es un iterador; y el iterador siempre evalúa como verdadero independientemente de su contenido. Además, los 'iterables' se agotarán en la primera ejecución a través del bucle, por lo que seguirán arrojando tuplas vacías a partir de entonces. ¿Correcto? – max

+0

@max: evaluará a 'True' porque' iterables' es una lista no vacía. ¿Has leído lo que he publicado? – SilentGhost

+0

Perdón, perdí tu respuesta :(Así que si se ejecuta en Python 2, sería cierto porque la lista de los iterables no está vacía, pero si se ejecuta en Python 3 (que asumí en mi comentario), sería cierto porque los iterables son un iterador , y el iterador siempre evalúa como verdadero, correcto? – max

7

Parece que se supone que este código debe leerse como código python-2.x. Ni siquiera se ejecuta correctamente en py3k.

Lo que ocurre en python-2.x es que map devuelve una lista de iteradores, cuando se llama next, devuelve un elemento de iterador, esos elementos combinados en tupla. Por lo tanto, dado

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

iterables es una lista de 2 iteradores, en cada iteración en el bucle while, elemento siguiente (primera restante) de iterador se consume (' 'A' y 'x', etc), y se obtuvieron como un elemento de una tupla, luego después de que se entregan los últimos elementos (en la tercera iteración) se levanta el generador StopIteration. while iterables siempre permanece True.

+0

+1 por la explicación python-2.x .. – max

+0

@max está etiquetado python-3. Primera frase dice que solo se trata de Python 3. ¿Por qué votando sobre la base de que la respuesta es para python-2? Ditto Ruby, o cualquier otra cosa que no sea python-3? –

+1

@RobertGrant porque referirse a python 2 era la única manera de explicar cómo la documentación oficial de Python aparentemente estaba completamente equivocada. – max

Cuestiones relacionadas