Python docs dice que cortar una lista devuelve una nueva lista.
Ahora, 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 la salida sería:
[4, 5, 3]
- ¿Cómo puede algo que está devolviendo algo venir del lado izquierdo de la expresión?
- Sí, leí los documentos y dice que es posible, ahora que cortar una lista devuelve una lista “nueva”, ¿por qué se modifica la lista original? No soy capaz de entender la mecánica detrás de esto.
Estás confundiendo dos operaciones distintas que usan una sintaxis muy similar:
1) rebanar:
b = a[0:2]
Esto hace una copia de la rebanada de a
y lo asigna a b
.
2) asignación de rebanadas:
a[0:2] = b
Esta reemplaza la rebanada de a
con los contenidos de b
.
Aunque la sintaxis es similar (¡me lo imagino por diseño!), estas son dos operaciones diferentes.
cuando especificas a
en el lado izquierdo de la =
operador, está utilizando Python asignación normalque 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 quiere usar asignación de rebanadas. 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]
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 segmento 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 a desempaquetado de tuplas. Por ejemplo, a[0:1] = [4, 5]
es equivalente a:
# Tuple Unpacking
a[0], a[1] = [4, 5]
Con el desempaquetado de tuplas, puede 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 puede insertar o quitar elementos.
Antes y después de todas estas operaciones, a
es la misma lista exacta. 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. De acuerdo a sentencias de asignación,
-
Si el lado izquierdo de la asignación es suscripción, Python llamará __setitem__
sobre ese objeto. a[i] = x
es equivalente a a.__setitem__(i, x)
.
-
Si el lado izquierdo de la asignación es un segmento, 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.
Al dividir el lado izquierdo de una operación de asignación, está especificando a qué elementos asignar.
cuando lo hiciste a[0:2] = [4,5]
asignó el lado izquierdo de la =
(la rebanada a[0:2]
) el valor en el lado derecho de la =
, [4,5]
.
@Mark Longair, lo siento, pensé que solo se suponía que se formateaba el código, no la salida
– Kartik Anand
16 mayo 2012 a las 17:07
Ver: 6.2 Declaraciones de cesión
– Josh Lee
16 mayo 2012 a las 17:10
sí, entiendo las asignaciones, pero este concepto de una nueva lista que se genera al cortar, me pone nervioso
– Kartik Anand
16 mayo 2012 a las 17:15
La asignación de @KartikAnand Slice es un escenario especial en el que no se crea una nueva lista. No tiene sentido crear un objeto sin un enlace de nombre en el lado izquierdo de un
=
, por lo que en lugar de descartar esto como una sintaxis no válida, Python lo convierte en algo más parecido a lo que cabría esperar. Dado que Python no tiene referencias, no funcionaría si el resultado de un corte cambiara la lista original. Obtienes una copia. Si proporcionó más información sobre su aplicación, es posible que podamos ayudarlo mejor a hacer las cosas de la manera ‘pythonic’. 🙂–Casey Kuball
16 mayo 2012 a las 23:21
@Darthfett No estoy trabajando en ninguna aplicación en este momento, sino que me estoy enseñando Python antes de empezar a ensuciarme las manos 🙂
– Kartik Anand
17 de mayo de 2012 a las 3:36