2009-02-01 10 views
7

¿Qué significa la última línea en el siguiente código?Problema al comprender la lista de Python comprensiones

import pickle, urllib                                      

    handle = urllib.urlopen("http://www.pythonchallenge.com/pc/def/banner.p") 
    data = pickle.load(handle) 
    handle.close() 

    for elt in data: 
     print "".join([e[1] * e[0] for e in elt]) 

Mi intento de problema:

  • "" ... .join usos se unen a -method texto vacío
  • correo [1] * e [0] multiplica dos valores posteriores en la secuencia, e
  • no estoy seguro de lo que es e
  • no estoy seguro, lo que significa, cuando se tiene algo antes de -loop, como: e[1] * e[0] for e in elt
+0

Realmente disfruté el desafío de Python cuando lo tomé hace un par de años. –

Respuesta

19

Tal vez explican mejor con un ejemplo:

print "".join([e[1] * e[0] for e in elt]) 

es la forma corta de

x = [] 
for e in elt: 
    x.append(e[1] * e[0]) 
print "".join(x) 

listas por comprensión son el azúcar simplemente sintáctica para for bucles, que hacen que una expresión de una secuencia de sentencias .

elt puede ser un objeto arbitrario, ya que lo carga desde salmueras, y e de la misma manera. El uso sugiere que es un tipo sequence, pero podría ser cualquier cosa que implemente el protocolo de secuencia.

+0

Creo que te refieres a "x.append (e [1] * e [0])" .. –

+0

@Marek: John tiene razón. –

+0

@John: Claro, está arreglado. –

4

[e[1] * e[0] for e in elt] es una lista de comprensión, que se evalúa a una lista mediante un bucle a través de otra lista, en este caso elt. Cada elemento en la nueva lista es e[1]*e[0], donde e es el elemento correspondiente en elt.

+0

e podría ser una tupla o dict – SilentGhost

+0

e puede ser cualquier cosa que implemente __getitem__. –

+0

Eso es verdad, hice una mala suposición. –

1

join() es un método de cadena, que funciona en un separador en la nueva cadena

>>> ':'.join(['ab', 'cd']) 
>>> 'ab:cd' 

y comprensión de lista no es necesario allí, generador bastaría

7

En primer lugar, es necesario poner http: // delante de la dirección URL, es decir: mango = urllib.urlopen ("http://www.pythonchallenge.com/pc/def/banner.p")

una expresión [e para el correo en aList] es un list comprehension que genera una lista de valores.

Con cadenas de Python, el operador * se utiliza para repetir una cadena. Pruebe a escribir en los comandos uno por uno en un intérprete y luego mirar los datos:

>>> data[0] 
[(' ', 95)] 

Esto nos muestra cada línea de datos es una tupla que contiene dos elementos.

Por lo tanto, la expresión e 1 * e [0] es efectivamente la cadena en e [0] repetida e 1 veces.

Por lo tanto, el programa dibuja un banner.

+0

Pero cambie los elementos: e [0] = 95 y e [1] = ''. –

+0

gracias por la corrección - Estoy tan acostumbrado a hacer lo "sensato" de multiplicar una cadena por un entero que la leí como si fuera así, ¡especialmente porque así es como se almacenan los datos! –

1

Andy's es una gran respuesta!

Si usted quiere ver en cada paso del bucle (con saltos de línea) probar esto:

for elt in data: 
    for e in elt: 
     print "e[0] == %s, e[1] == %d, which gives us: '%s'" % (e[0], e[1], ''.join(e[1] * e[0])) 
+0

Da una larga lista de: e [0] ==% s, e [1] ==% d –

+0

@Masi: Gracias por notar eso. Quizás el carácter de salto de línea ("\") estaba causando problemas. Lo he eliminado de la respuesta. – bernie

2

La pregunta en sí misma ya ha sido contestado completamente pero me gustaría añadir que una lista por comprensión también es compatible con el filtrado. Su línea original

print "".join([e[1] * e[0] for e in elt]) 

podría, por ejemplo, se convierten en

print "".join([e[1] * e[0] for e in elt if len(e) == 2]) 

a operar sólo en los elementos de elt que tienen dos elementos.

+0

¡Digno de comentar! – ChuckCottrill

Cuestiones relacionadas