2011-03-03 14 views
60

En Python uno puede hacer:semántica asignación múltiple

a, b = 1, 2 
(a, b) = 1, 2 
[a, b] = 1, 2 

he comprobado el código de bytes generados utilizando dis y son idénticos.
Entonces, ¿por qué permitir esto en absoluto? ¿Alguna vez necesitaría uno de estos en lugar de los otros?

+28

+1 para comprobar el código de bytes generados son –

Respuesta

65

Un caso cuando necesitas incluir más estructura en el lado izquierdo de la tarea es cuando le pides a Python que desempaquete una secuencia un poco más complicada. Ej .:

# Works 
>>> a, (b, c) = [1, [2, 3]] 

# Does not work 
>>> a, b, c = [1, [2, 3]] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: need more than 2 values to unpack 

Esto ha demostrado ser útil para mí en el pasado, por ejemplo, cuando se utiliza enumerar para iterar sobre una secuencia de 2-tuplas. Algo así como:

>>> d = { 'a': 'x', 'b': 'y', 'c': 'z' } 
>>> for i, (key, value) in enumerate(d.iteritems()): 
...  print (i, key, value) 
(0, 'a', 'x') 
(1, 'c', 'z') 
(2, 'b', 'y') 
+1

¡Voto a favor de mostrar un gran caso de uso en el que nunca pensé! – kindall

+2

Mejor: use un OrderedDict y 'i' tendrá aún más significado. – infogulch

1

También son iguales porque la asignación ocurre de derecha a izquierda y a la derecha, tiene un tipo, que es una secuencia de dos elementos. Cuando se realiza la llamada de asignación, la secuencia se desempaqueta y busca los elementos correspondientes para hacer coincidir y dar a esos valores. Sí, de una sola manera debería estar bien en este caso donde la secuencia se desempaqueta en los elementos respectivos.

+0

lo que implica que hay casos en que estos podrían funcionar de manera diferente? – Aillyn

+0

En el caso, cuando el LHS es un identificador único, solo se realiza una llamada STORE_FAST. De lo contrario, es todo lo mismo. –

9

tuplas Python menudo se pueden escribir con o sin los paréntesis:

a = 1, 2, 3 

es equivalente a

a = (1, 2, 3) 

En algunos casos, es necesario paréntesis para resolver ambigüedades, por ejemplo, si desea pasar la tupla (1, 2) a la función f, tendrá que escribir f((1, 2)). Debido a que a veces se necesitan los paréntesis, siempre se les permite coherencia, al igual que siempre se puede escribir (a + b) en lugar de a + b.

Si se desea expandir una secuencia anidada, también es necesario paréntesis:

a, (b, c) = 1, (2, 3) 

No parece haber una razón para que también entre corchetes, y la gente rara vez lo hacen.

+1

¿Lo consideraría un error cuando se permiten corchetes en este contexto? Para mí, este comportamiento parece violar (al menos): 'Debería haber una, y preferiblemente solo una, forma obvia de hacerlo. Y' Los casos especiales no son lo suficientemente especiales como para romper las reglas. Gracias – eat

+1

@ comer: definitivamente no llamaría esto un error. Está claramente [documentado] (http://docs.python.org/reference/simple_stmts.html#assignment-statements). Me estoy preguntando sobre la razón de esta decisión de diseño. –

+2

OK, no es un error, pero cuando dices que 'solo me pregunto sobre el fundamento de esta decisión de diseño' también me resulta curioso y perplejo de lo que sería (incluso solo) un caso de uso justificable para' [...] = ' ¿entonces?. Gracias – eat

0

Un paréntesis abierto permite una asignación de varias líneas. Por ejemplo, al leer una fila desde csv.reader(), hace que el código sea más legible (si es menos eficiente) para cargar la lista en variables nombradas con una única asignación.

Comenzando con un paréntesis evita largas o \ líneas escapadas.

(a, b, c) = [1, 2, 3]

(Imagínese que más y más largos nombres de variables)

0

Al desembalar un solo elemento iterable, la sintaxis de la lista es más bonita:

a,=f() # comma looks out of place 
(a,)=f() # still odd 
[a]=f() # looks like every other list