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

5 minutos de lectura

¿Como funciona la asignacion con segmentos de lista
Kartik Anand

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] 
  1. ¿Cómo puede algo que está devolviendo algo venir del lado izquierdo de la expresión?
  2. 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.

  • @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

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.

  • Esa es mi duda, en el segundo caso por que no es el trozo de una, una nueva lista??

    – Kartik Anand

    16 mayo 2012 a las 17:12

  • @KartikAnand Porque no lo es. Eso no es lo que especifica el idioma.

    – Marcin

    16 mayo 2012 a las 17:12

  • Para ser claros, “toma una porción de” realmente significa “hacer una copia de una porción de”, que es de donde proviene parte de la confusión.

    – Mark Ransom

    16 mayo 2012 a las 17:12

  • @KartikAnand: Básicamente, sí. El intérprete sabe cuál es cuál y los maneja adecuadamente.

    – ENP

    16 mayo 2012 a las 17:21

  • @Dubslow: puedes hacerlo usando el itertools módulo. Para tu caso usa la función islicecon start=1, stop=None. Esto evitará cualquier copia y utilizará la evaluación perezosa (en su caso, acceso perezoso a la lista original).

    – Espiros

    25 de junio de 2015 a las 9:27

1646962328 210 ¿Como funciona la asignacion con segmentos de lista
casey kuball

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.

  • Similar pero no idéntico, ya que puede tener un número desigual de elementos a la izquierda y a la derecha.

    – Mark Ransom

    16 mayo 2012 a las 17:14

  • @MarkRansom Ese es un punto excelente, he agregado más información para que esto sea obvio.

    –Casey Kuball

    16 mayo 2012 a las 17:26

  • Es a[:] = some_list equivalente a a = some_list[:] o a = some_list?

    – jadkik94

    17 mayo 2012 a las 10:42

  • @ jadkik94 Ninguno. a[:] = some_list establece cada elemento de a ser los de some_list. Hacer cualquiera de los que mencionas cambiaría lo que a es. Por ejemplo: a = [1, 2, 3] b = a a[:] = [4, 5, 6] a is b. La última línea sería falsa si cambiara ael valor de , en lugar de mutarlo.

    –Casey Kuball

    17 mayo 2012 a las 13:16

  • @CaseyKuball ¿El valor de start: stop: step siempre debe ser positivo cuando estamos haciendo una asignación de rebanadas?

    – huelguistas

    20 de septiembre de 2020 a las 15:33

¿Como funciona la asignacion con segmentos de lista
Stan

Me encontré con la misma pregunta antes y está relacionada con la especificación del idioma. De acuerdo a sentencias de asignación,

  1. 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).

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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad