2012-08-03 14 views
5

Soy nuevo con Python (con Java como básico). Leí Dive Into Python libros, en el Capítulo 3 encontré aproximadamente Multi-Variable Assignment. Tal vez algunos de ustedes me puede ayudar a entender lo que sucede en este código de abajo:Falta de comprensión de las asignaciones de variables múltiples Python

>>> params = {1:'a', 2:'b', 3:'c'} 
>>> params.items() # To display list of tuples of the form (key, value). 
[(1, 'a'), (2, 'b'), (3, 'c')] 

>>> [a for b, a in params.items()] #1 
['a', 'b', 'c'] 
>>> [a for a, a in params.items()] #2 
['a', 'b', 'c'] 
>>> [a for a, b in params.items()] #3 
[ 1 , 2 , 3 ] 
>>> [a for b, b in params.items()] #4 
[ 3 , 3 , 3 ] 

Lo que entiendo hasta ahora es la #1 y tiene #2 misma salida, que deben mostrarse los valores de la tupla. #3 muestra la clave de tupla, y #4 solo muestra la última clave de la lista de tuplas.

No entiendo el uso de la variable a y variables b para cada caso anterior:

  1. a for b, a ... -> mostrar los valores
  2. a for a, a ... -> mostrar los valores
  3. a for a, b ... - > mostrar las teclas
  4. a for b, b ... -> mostrar la última clave

¿Alguien puede elaborar el flujo del lazo para cada caso anterior?

+0

¿Cuál es tu pregunta? – jtbandes

+0

Quiero entender de qué sirve la variable 'a' y' b' en # 1, # 2, # 3 y # 4. – Crazenezz

+0

¿De cuál (s) estás confundido? – dghubble

Respuesta

8

La lista por comprensión no utiliza más o menos traduce de la siguiente manera:

[a for b, a in params.items()] 

convierte

result = [] 
for item in params.items(): 
    b = item[0] 
    a = item[1] 
    result.append(a) 

[a for a, a in params.items()] 

convierte

result = [] 
for item in params.items(): 
    a = item[0] 
    a = item[1] # overwrites previous value of a, hence this yields values, 
       # not keys 
    result.append(a) 

[a for a, b in params.items()] 

convierte

result = [] 
for item in params.items(): 
    a = item[0] 
    b = item[1] 
    result.append(a) 

[a for b, b in params.items()] 

convierte

result = [] 
for item in params.items(): 
    b = item[0] 
    b = item[1] 
    result.append(a) # note use of a here, which was not assigned 

Este último es especial. Solo funcionó porque había utilizado la variable a en una declaración anterior, y el último valor que le había sido asignado era 3. Si ejecuta esta declaración primero, obtendría un error.

6

En los cuatro casos, los nombres en la tupla están ligados a cada uno de los elementos del par de la secuencia en orden. La cuarta instancia es un ejemplo de (mal) comportamiento en Python 2.x; el nombre queda ligado al último objeto que tenía, incluso fuera del LC. Este comportamiento se soluciona en 3.x.

>>> [x for x in (1, 2, 3)] 
[1, 2, 3] 
>>> x 
3 

3>> [x for x in (1, 2, 3)] 
[1, 2, 3] 
3>> x 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'x' is not defined 
+1

Buena nota acerca de 2.x "leaking" LC vars –

3

Una tupla solo está empaquetando las variables juntas.Usted obtiene estos pares cuando llama al

params.items() 

como usted mismo se ha anotado en los comentarios.

para desempaquetar una tupla todo lo que tiene que hacer es esto:

>>> a, b = (2, 3) 
>>> a 
2 
>>> b 
3 

Lo mismo se hace cuando se utiliza listas por comprensión.

>>> [a for a, b in [(2, 3), (4, 5)]] 
[2, 4] 

aquí a saca el primer elemento de la tupla para cada tupla de la lista. Este es el # 1 en su caso usando la lista de params en lugar de mi lista corta.

Si en lugar de escribir

>>> [b for a, b in [(2, 3), (4, 5)]] 
[3, 5] 

se obtiene el segundo elemento. Esto corresponde a tu # 3.

Los otros dos realmente no tienen sentido. En # 2 tiene

>>> [a for a, a in [(2, 3), (4, 5)]] 
[3, 5] 
>>> a,a = (2,3) 
>>> a 
3 

que acaba permite a un ser primero el primero y luego directamente sobrescribe con el segundo argumento en cada desembalaje. Puedes ver que esto mismo sucede con la tupla simple.

Última # 4 es simplemente retorcer. Si no hubieras utilizado una como variable, esto no habría funcionado ya que a continuación, no existe.

>>> [a for b, b in [(2, 3), (4, 5)]] 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
NameError: name 'a' is not defined 

Espero que responda a sus preguntas.

Cuestiones relacionadas