¿Cómo funciona la asignación con sectores de lista?

Resuelto Kartik Anand asked hace 12 años • 5 respuestas

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] 
  1. ¿Cómo puede algo que devuelve algo aparecer en el lado izquierdo de la expresión?
  2. 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.
Kartik Anand avatar May 17 '12 00:05 Kartik Anand
Aceptado

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 ay lo asigna a b.

2) asignación de sectores:

a[0:2] = b

Esto reemplaza la porción de acon el contenido de b.

Aunque la sintaxis es similar (¡me imagino que por diseño!), son dos operaciones diferentes.

NPE avatar May 16 '2012 17:05 NPE

Cuando especifica aen el lado izquierdo del =operador, está utilizando la asignación normal de Python , que cambia el nombre aen el contexto actual para que apunte al nuevo valor. Esto no cambia el valor anterior al que aapuntaba.

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, ahay exactamente la misma lista. Python simplemente proporciona un buen azúcar sintáctico para modificar una lista en el lugar.

Casey Kuball avatar May 16 '2012 17:05 Casey Kuball

Me encontré con la misma pregunta antes y está relacionada con la especificación del idioma. Según las declaraciones de asignación ,

  1. Si el lado izquierdo de la asignación es una suscripción, Python llamará __setitem__a ese objeto. a[i] = xes equivalente a a.__setitem__(i, x).

  2. 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 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.

Stan avatar Feb 25 '2016 16:02 Stan