¿Cómo funciona la asignación con sectores de lista?
Los documentos de Python dicen que dividir una lista devuelve una nueva lista.
Ahora bien, si se devuelve una lista "nueva", tengo las siguientes preguntas relacionadas con "Asignación a sectores"
a = [1, 2, 3]
a[0:2] = [4, 5]
print a
Ahora el resultado sería:
[4, 5, 3]
- ¿Cómo puede algo que devuelve algo aparecer en el lado izquierdo de la expresión?
- Sí, leí los documentos y dice que es posible, ahora que al dividir una lista se devuelve una lista "nueva", ¿por qué se modifica la lista original? No puedo entender la mecánica detrás de esto.
Estás confundiendo dos operaciones distintas que utilizan una sintaxis muy similar:
1) rebanar:
b = a[0:2]
Esto hace una copia del segmento de a
y lo asigna a b
.
2) asignación de sectores:
a[0:2] = b
Esto reemplaza la porción de a
con el contenido de b
.
Aunque la sintaxis es similar (¡me imagino que por diseño!), son dos operaciones diferentes.
Cuando especifica a
en el lado izquierdo del =
operador, está utilizando la asignación normal de Python , que cambia el nombre a
en el contexto actual para que apunte al nuevo valor. Esto no cambia el valor anterior al que a
apuntaba.
Al especificar a[0:2]
en el lado izquierdo del =
operador, le está indicando a Python que desea utilizar la asignación de sectores . La asignación de sectores es una sintaxis especial para listas, donde puede insertar, eliminar o reemplazar contenidos de una lista:
Inserción :
>>> a = [1, 2, 3]
>>> a[0:0] = [-3, -2, -1, 0]
>>> a
[-3, -2, -1, 0, 1, 2, 3]
Eliminació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
La asignación de sectores proporciona una función similar al desempaquetado de tuplas . Por ejemplo, a[0:1] = [4, 5]
equivale a:
# Tuple Unpacking
a[0], a[1] = [4, 5]
Con el desempaquetado de tuplas, puedes modificar listas no secuenciales:
>>> a
[4, 5, 3]
>>> a[-1], a[0] = [7, 3]
>>> a
[3, 5, 7]
Sin embargo, el desempaquetado de tuplas se limita al reemplazo, ya que no se pueden insertar ni eliminar elementos.
Antes y después de todas estas operaciones, a
hay exactamente la misma lista. Python simplemente proporciona un buen 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 las declaraciones de asignación ,
Si el lado izquierdo de la asignación es una suscripción, Python llamará
__setitem__
a ese objeto.a[i] = x
es equivalente aa.__setitem__(i, x)
.Si el lado izquierdo de la asignación es un segmento, Python también llamará a
__setitem__
, pero con argumentos diferentes:a[1:4]=[1,2,3]
es equivalente aa.__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.