Orden de asignación y evaluación múltiple en Python

¿Cuál es la diferencia entre las siguientes expresiones de Python:

# First: x,y = y,x+y # Second: x = y y = x+y 

Primero da resultados diferentes que el segundo .

p.ej,

Primero:

 >>> x = 1 >>> y = 2 >>> x,y = y,x+y >>> x 2 >>> y 3 

Segundo:

     >>> x = 1 >>> y = 2 >>> x = y >>> y = x+y >>> x 2 >>> y 4 

    y es 3 en primero y 4 en segundo

    En una statement de asignación, el lado derecho siempre se evalúa por completo antes de realizar el ajuste real de las variables. Asi que,

     x, y = y, x + y 

    evalúa y (llamemos al resultado ham ), evalúa x + y (llama a ese spam ), luego establece x en ham y y en spam . Es decir, es como

     ham = y spam = x + y x = ham y = spam 

    Por el contrario,

     x = y y = x + y 

    establece x a y , luego establece y a x (que == y ) más y , por lo que es equivalente a

     x = y y = y + y 

    Se explica en los documentos en la sección titulada “Orden de evaluación” :

    … mientras evalúa una asignación, el lado derecho se evalúa antes que el lado izquierdo.

    La primera expresión:

    1. Crea una tupla temporal con valor y,x+y
    2. Asignado a otra tupla temporal
    3. Extrae la tupla a las variables x e y

    La segunda statement es en realidad dos expresiones, sin el uso de la tupla.

    La sorpresa es que la primera expresión es en realidad:

     temp=x x=y y=temp+y 

    Puede obtener más información sobre el uso de comas en ” Formas entre paréntesis “.

    En el segundo caso, asigna x+y a x

    En el primer caso, el segundo resultado ( x+y ) se asigna a y

    Es por esto que obtienes diferentes resultados.

    Después de su edición

    Esto sucede porque, en la statement

     x,y = y,x+y 

    todas las variables en el miembro derecho se evalúan y, luego, se almacenan en los miembros izquierdos. Así que primero proceda con el miembro derecho, y segundo con el miembro izquierdo.

    En el segundo enunciado

     x = y y = x + y 

    primero evalué y y lo asigné a x ; de esa manera, la sum de x+y es equivalente a una sum de y+y y no de x+x que es el primer caso.

    El primero es una tarea similar a una tupla:

     x,y = y,x+y 

    Donde x es el primer elemento de la tupla, e y es el segundo elemento, entonces lo que estás haciendo es:

     x = y y = x+y 

    ¿Dónde está el segundo haciendo una asignación directa?

     x=y x=x+y 
     a, b = 0, 1 while b < 10: print(b) a, b = b, a+b 

    Salida

     1 1 2 3 5 8 

    Las variables a y b obtienen simultáneamente los nuevos valores 0 y 1, los mismos a, b = b, a + b, ayb se asignan simultáneamente.

    Vamos a asimilar la diferencia.

    x, y = y, x + y Es x tuple xsignment, mexns (x, y) = (y, x + y) , igual que (x, y) = (y, x)

    Stxrt de x ejemplo rápido:

     x, y = 0, 1 #equivxlent to (x, y) = (0, 1) #implement xs x = 0 y = 1 

    Cuando llega a (x, y) = (y, x + y) ExFP, haga que x intente directamente

     x, y = 0, 1 x = y #x=y=1 y = x + y #y=1+1 #output In [87]: x Out[87]: 1 In [88]: y Out[88]: 2 

    Sin embargo,

     In [93]: x, y = y, x+y In [94]: x Out[94]: 3 In [95]: y Out[95]: 5 

    El resultado es diferente del primer bash.

    Thx es porque Python primero evalúa la mano derecha x+y Por lo tanto, equivale a:

     old_x = x old_y = y c = old_x + old_y x = old_y y = c 

    En resumen, x, y = y, x+y significa,
    x intercambios para obtener el antiguo valor de y ,
    y intercambia para obtener la sum del valor antiguo x y el valor antiguo y ,

    Recientemente comencé a usar Python y esta “característica” me desconcertó. Aunque hay muchas respuestas dadas, publicaré mi entendimiento de todos modos.

    Si quiero intercambiar los valores de dos variables, en JavaScipt, haría lo siguiente:

     var a = 0; var b = 1; var temp = a; a = b; b = temp; 

    Necesitaría una tercera variable para mantener temporalmente uno de los valores. Un intercambio muy sencillo no funcionaría, porque ambas variables terminarían con el mismo valor.

     var a = 0; var b = 1; a = b; // b = 1 => a = 1 b = a; // a = 1 => b = 1 

    Imagine tener dos cubos diferentes (rojo y azul) y tener dos líquidos diferentes (agua y aceite) en ellos, respectivamente. Ahora, intente cambiar los cubos / líquidos (agua en azul y aceite en un cubo rojo). No puedes hacerlo a menos que tengas un cubo extra.

    Python trata esto con una forma / solución más “limpia”: Asignación de tuplas .

     a = 0 b = 1 print(a, b) # 0 1 # temp = a # a = b # b = temp a, b = b, a # values are swapped print(a, b) # 1 0 

    Supongo que, de esta manera, Python está creando las variables “temporales” automáticamente y no tenemos que preocuparnos por ellas.