valores una tuplas tupla son qué que obtener lista las entre diferencia diccionario cadenas python list indexing tuple-packing

python - una - tuplas append



El orden de desempaquetado de Tuple cambia los valores asignados (4)

Prerrequisitos : 2 puntos importantes

Introducción

cuando haces a,b = c,d los valores de d se almacenan primero. Luego comenzando desde el lado izquierdo, el valor de a se cambia primero a c y luego el valor de b se cambia a d .

La captura aquí es que si hay efectos secundarios en la ubicación de b al cambiar el valor de a , entonces d se asigna a la b posterior , que es la b afectada por el efecto secundario de a .

Caso de uso

Ahora llegando a tu problema

En el primer caso,

nums = [1, 2, 0] nums[nums[0]], nums[0] = nums[0], nums[nums[0]]

nums[0] es inicialmente 1 y nums[nums[0]] es 2 porque evalúa nums[1] . Por lo tanto, 1,2 ahora está almacenado en la memoria.

Ahora el desempaquetado de tuplas ocurre desde el lado izquierdo, por lo que

nums[nums[0]] = nums[1] = 1 # NO side Effect. nums[0] = 2

por lo tanto, print nums se imprimirá [2, 1, 0]

Sin embargo, en este caso

nums = [1, 2, 0] nums[0], nums[nums[0]] = nums[nums[0]], nums[0]

nums[nums[0]], nums[0] pone 2,1 en la pila como en el primer caso.

Sin embargo, en el lado izquierdo, que es nums[0], nums[nums[0]] , el cambio de nums[0] tiene un efecto secundario ya que se usa como índice en nums[nums[0]] . Así

nums[0] = 2 nums[nums[0]] = nums[2] = 1 # NOTE THAT nums[0] HAS CHANGED

nums[1] permanece sin cambios en el valor 2 . por lo tanto, print nums se imprimirá [2, 2, 1]

Creo que los dos son idénticos.

nums = [1, 2, 0] nums[nums[0]], nums[0] = nums[0], nums[nums[0]] print nums # [2, 1, 0] nums = [1, 2, 0] nums[0], nums[nums[0]] = nums[nums[0]], nums[0] print nums # [2, 2, 1]

Pero los resultados son diferentes.
¿Por qué los resultados son diferentes? (¿por qué es el segundo resultado?)


En el primer ejemplo, lo que ocurre es que nums [1] se establece en 1, y luego nums [0] se establece en 2, como era de esperar.

En el segundo ejemplo, nums [0] se establece en 2, y luego nums [2] se establece en 1. Esto se debe a que, en este caso, los nums del lado izquierdo [nums [0]] realmente hacen referencia a nums [2 ] cuando ocurre la asignación, porque nums [0] acababa de establecerse en 2.


Es debido a que la prioridad de asignación de Python es de izquierda a derecha. Así que en el siguiente código:

nums = [1, 2, 0] nums[nums[0]], nums[0] = nums[0], nums[nums[0]]

Primero asignó los nums[0] a nums[nums[0]] significa nums[1]==1 y luego dado que las listas son objetos mutables los nums serían:

[1,1,0]

y luego nums[nums[0]] se asignarán a nums[0] que significa nums[0]==2 y:

nums = [2,1,0]

Y así para la segunda parte.

Tenga en cuenta que el punto importante aquí es que los objetos de la lista son mutables y cuando lo cambia en un segmento de código puede cambiarse in situ. por lo tanto, afectará al resto del código.

Orden de evaluación

Python evalúa expresiones de izquierda a derecha. Tenga en cuenta que al evaluar una tarea, el lado derecho se evalúa antes que el lado izquierdo.


Puede definir una clase para seguir el proceso:

class MyList(list): def __getitem__(self, key): print(''get '' + str(key)) return super(MyList, self).__getitem__(key) def __setitem__(self, key, value): print(''set '' + str(key) + '', '' + str(value)) return super(MyList, self).__setitem__(key, value)

Para el primer método:

nums = MyList([1, 2, 0]) nums[nums[0]], nums[0] = nums[0], nums[nums[0]]

la salida es:

get 0 get 0 get 1 get 0 set 1, 1 set 0, 2

Mientras que el segundo método:

nums = MyList([1, 2, 0]) nums[0], nums[nums[0]] = nums[nums[0]], nums[0]

la salida es:

get 0 get 1 get 0 set 0, 2 get 0 set 2, 1

En ambos métodos, las primeras tres líneas están relacionadas con la generación de tuplas, mientras que las últimas tres líneas están relacionadas con las asignaciones. La tupla del lado derecho del primer método es (1, 2) y el segundo método es (2, 1) .

En la etapa de asignación, el primer método obtiene nums[0] que es 1 , y establece nums[1] = 1 , luego nums[0] = 2 , segundo método asigna nums[0] = 2 , luego obtiene nums[0] que es 2 , y finalmente establece nums[2] = 1 .