¿Por qué invertir una lista usando la notación de división con 0 como “detener” no devuelve la lista completa?

5 minutos de lectura

avatar de usuario de user737079
usuario737079

En el siguiente ejemplo:

foo = ['red', 'white', 'blue', 1, 2, 3]

foo[0:6:1] imprimirá todos los elementos en foo. Sin embargo, foo[6:0:i-1] omitirá el elemento 1 o 0.

>>> foo[6:0:-1]
[3, 2, 1, 'blue', 'white']

Entiendo que puedo usar foo.reverse() o foo[::-1] para imprimir la lista al revés, pero ¿por qué no foo[6:0:-1] imprimir la lista completa?

  • Tenga en cuenta también el foo[7:None:-1] posibilidad 🙂

    – tzot

    27 mayo 2011 a las 11:00

  • Nunca usé python antes de tratar de entender la notación de corte, mi pregunta es por qué foo[6:0:-1] no está arrojando un error de índice, ¿a Python no le importa? porque el índice 6 no está disponible en la matriz de ejemplo anterior.

    – Mubashar

    11 de agosto de 2013 a las 9:30

  • @MubasharAhmad Slicing no está indexando y no arroja ningún error cuando va más allá de los límites. Sin embargo, la indexación arroja una excepción cuando está fuera de los límites.

    – abrazo

    13 de abril de 2014 a las 0:42


Avatar de usuario de Andrew Clark
andres clark

Notación de corte en resumen:

[ <first element to include> : <first element to exclude> : <step> ]

Si desea incluir el primer elemento al invertir una lista, deje el elemento del medio vacío, así:

foo[::-1]

También puede encontrar buena información sobre los segmentos de Python en general aquí:
Explicar la notación de corte de Python

  • Esto: [ <first element to include> : <first element to exclude> : <step> ] es la explicación más clara de la sintaxis de corte que he visto. Llamarlo “primer elemento a excluir” realmente hace obvio lo que está pasando.

    – Schof

    5 de mayo de 2011 a las 18:23


  • ¿Qué pasa con el corte negativo con pasos negativos? Todavía no lo entiendo.

    – abrazo

    13 de abril de 2014 a las 1:39

  • Cuando usa un índice negativo como <first element to include> o <first element to exclude> está indexando desde el final de la lista, por lo que -1 es el último elemento, -2 es el penúltimo elemento, etc. Entonces, por ejemplo, x[-1:-4:-1] obtendría los últimos tres elementos de x en orden inverso. Entonces podría interpretar esto como “moviéndose hacia atrás, tome cada elemento (-1 paso) del último elemento de la lista (-1 <first element to include>) hasta pero sin incluir el cuarto elemento desde el final (-4 <first element to include>)”.

    – Andrés Clark

    14/04/2014 a las 16:24

  • Al dar marcha atrás (es decir, si <step> es -1), me ayuda a pensar <first element to include, moving from right to left>. Entonces, para obtener la n elementos “más a la izquierda” de una lista en orden inverso: foo[n-1::-1]. Para obtener el n elementos “más a la derecha” en orden inverso: foo[-1:-n-1:-1].

    – djvg

    8 oct 2018 a las 17:03


  • ¿Cómo se hace que el primer elemento excluya “el elemento anterior foo[0]“?

    – BolígrafoBen

    17 de enero de 2020 a las 18:49

Si tiene problemas para recordar la notación de corte, puede intentar hacer lo hokey cokey:

[In: Out: Shake it all about]

[First element to include: First element to leave out: The step to use]

YMMV

Esta respuesta puede estar un poco desactualizada, pero podría ser útil para alguien que se quedó con el mismo problema. Puede obtener una lista inversa con un final arbitrario: hasta un índice 0, aplicando un segundo segmento en el lugar como este:

>>> L = list(range(10))
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> (start_ex, end) = (7, 0)
>>> L[end:start_ex][::-1]
[6, 5, 4, 3, 2, 1, 0]

  • En realidad, esto es bastante útil, porque puede usar la misma sintaxis para todos los casos. No tienes que tratar el 0 como un caso especial.

    – Tom Zych

    22 de diciembre de 2018 a las 21:12

  • Esto tiene más sentido que el comportamiento predeterminado de Python/numpy para el corte negativo, porque normalmente uno quiere cortar y/o invertir una imagen o tensor alineado a un borde determinado, mientras que Python/numpy pierde esa última fila/columna de los datos o_O.

    –Dwayne Robinson

    12 de febrero de 2020 a las 0:30

Avatar de usuario de Fred Nurk
fred nurk

… por qué foo[6:0:-1] no imprime la lista completa?

Porque el valor medio es el exclusivo, en lugar de un valor de parada inclusivo. Él notación de intervalos es [start, stop).

This is exactly how [x]trabajos de rango:

>>> range(6, 0, -1)
[6, 5, 4, 3, 2, 1]

Esos son los índices que se incluyen en la lista resultante y no incluyen 0 para el primer elemento.

>>> range(6, -1, -1)
[6, 5, 4, 3, 2, 1, 0]

Otra forma de verlo es:

>>> L = ['red', 'white', 'blue', 1, 2, 3]
>>> L[0:6:1]
['red', 'white', 'blue', 1, 2, 3]
>>> len(L)
6
>>> L[5]
3
>>> L[6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

El índice 6 está más allá (una pasada, precisamente) de los índices válidos para L, por lo que se excluye del rango como el valor de parada excluido:

>>> range(0, 6, 1)
[0, 1, 2, 3, 4, 5]

Todavía le da índices para cada elemento de la lista.

avatar de usuario de foki
foki

Esta es una muy buena pregunta y, en mi opinión, ninguna de las respuestas anteriores responde realmente a la pregunta que se hace. En parte porque una respuesta intelectualmente honesta puede revelar una debilidad del sistema tipo Python. Y la misma debilidad existe en algunos otros idiomas.

Una respuesta intelectualmente más honesta probablemente sería:
El corte de Python no se generaliza bien.

Precisamente, uno puede atravesar una colección en una dirección con collection[begin:end] pero collection[end:begin:-1] No funciona. No funciona porque el primer índice es 0 pero el “índice antes del primer índice” no es -1. Por lo tanto, collection[end:-1:-1] no evalúa lo que esperaríamos legítimamente.

Él [first to include : first to exclude : step] la explicación es defectuosa. Si “primero en excluir” es el anterior al primer elemento, no puede expresarlo de la misma manera que lo haría en el caso de que quisiera incluir ese mismo primer elemento.

En conclusión, no estás loco por esperar generalidad, simplemente no está allí.

Puede hacer que funcione si utiliza un valor de parada negativo. Prueba esto:

foo[-1:-7:-1]

Avatar de usuario de Ashmita Dutta
Ashmita Dutta

Utilizar

>>>foo[::-1]

Esto muestra el reverso de la lista desde el elemento final hasta el inicio,

¿Ha sido útil esta solución?