Solución:
Está confundiendo dos operaciones distintas que utilizan una sintaxis muy similar:
1) rebanar:
b = a[0:2]
Esto hace una copia de la porción de a
y lo asigna a b
.
2) asignación de rebanadas:
a[0:2] = b
Esta reemplaza la rebanada de a
con el contenido de b
.
Aunque la sintaxis es similar (¡imagino por diseño!), Estas son dos operaciones diferentes.
Cuando especificas a
en el lado izquierdo de la =
operador, estás usando Python asignación normal, que cambia el nombre a
en el contexto actual para apuntar al nuevo valor. Esto no cambia el valor anterior al que a
estaba señalando.
Especificando a[0:2]
en el lado izquierdo de la =
operador, le está diciendo a Python que desea usar Asignación de rebanadas. Slice Assignment es una sintaxis especial para listas, donde puede insertar, eliminar o reemplazar contenido de una lista:
Inserción:
>>> a = [1, 2, 3]
>>> a[0:0] = [-3, -2, -1, 0]
>>> a
[-3, -2, -1, 0, 1, 2, 3]
Supresión:
>>> a
[-3, -2, -1, 0, 1, 2, 3]
>>> a[2:4] = []
>>> a
[-3, -2, 1, 2, 3]
Reemplazo:
>>> a
[-3, -2, 1, 2, 3]
>>> a[:] = [1, 2, 3]
>>> a
[1, 2, 3]
Nota:
La longitud del corte puede ser diferente de la longitud de la secuencia asignada, cambiando así la longitud de la secuencia objetivo, si la secuencia objetivo lo permite. – fuente
Slice Assignment proporciona una función similar a Tuple Unpacking. Por ejemplo, a[0:1] = [4, 5]
es equivalente a:
# Tuple Unpacking
a[0], a[1] = [4, 5]
Con Tuple Unpacking, puede modificar listas no secuenciales:
>>> a
[4, 5, 3]
>>> a[-1], a[0] = [7, 3]
>>> a
[3, 5, 7]
Sin embargo, el desembalaje de tuplas se limita al reemplazo, ya que no puede insertar ni quitar elementos.
Antes y después de todas estas operaciones, a
es la misma lista exacta. Python simplemente proporciona un agradable azúcar sintáctico para modificar una lista en el lugar.
Me encontré con la misma pregunta antes y está relacionada con la especificación del idioma. Según declaraciones de asignación,
-
Si el lado izquierdo de la asignación es una suscripción, Python llamará
__setitem__
en ese objeto.a[i] = x
es equivalente aa.__setitem__(i, x)
. -
Si el lado izquierdo de la asignación es slice, Python también llamará
__setitem__
, pero con diferentes argumentos:
a[1:4]=[1,2,3]
es equivalente a
a.__setitem__(slice(1,4,None), [1,2,3])
Es por eso que el segmento de lista en el lado izquierdo de ‘=’ se comporta de manera diferente.