python list slice

python - Rebanada extendida que va al comienzo de la secuencia con zancada negativa



range python (9)

Ten paciencia conmigo mientras te explico mi pregunta. Vaya al título en negrita si ya comprende la indexación de la lista de sectores extendidos.

En python, puede indexar listas usando notación de división. Aquí hay un ejemplo:

>>> A = list(range(10)) >>> A[0:5] [0, 1, 2, 3, 4]

También puede incluir un paso, que actúa como un "paso":

>>> A[0:5:2] [0, 2, 4]

La zancada también se permite que sea negativa, lo que significa que los elementos se recuperan en orden inverso:

>>> A[5:0:-1] [5, 4, 3, 2, 1]

¡Pero espera! Quería ver [4, 3, 2, 1, 0] . Oh, ya veo, necesito disminuir los índices de inicio y fin:

>>> A[4:-1:-1] []

¿Que pasó? Está interpretando que -1 está al final de la matriz, no al principio. Sé que puedes lograr esto de la siguiente manera:

>>> A[4::-1] [4, 3, 2, 1, 0]

Pero no puedes usar esto en todos los casos. Por ejemplo, en un método que ha pasado índices.

Mi pregunta es:

¿Hay alguna buena forma pitonica de usar sectores extendidos con pasos negativos e índices de inicio y final explícitos que incluyen el primer elemento de una secuencia?

Esto es lo que he propuesto hasta ahora, pero parece insatisfactorio.

>>> A[0:5][::-1] [4, 3, 2, 1, 0]


Creo que lo siguiente no te satisface:

def getReversedList(aList, end, start, step): if step < 0 and start == 0: return aList[end::step] return aList[end:start:step]

o lo hace? :-)


Ok, creo que esto es probablemente tan bueno como lo obtendré. Gracias a Abgan por desatar la idea. Esto se basa en el hecho de que None en un segmento se trata como si fuera un parámetro faltante. Alguien tiene algo mejor?

def getReversedList(aList, end, start, step): return aList[end:start if start!=-1 else None:step]

editar: verificar para start==-1 , no 0

Esto todavía no es ideal, porque estás criticando el comportamiento habitual de -1. Parece que el problema aquí es dos definiciones superpuestas de lo que se supone que sucederá. Quien gane quita las invocaciones válidas que buscan la otra intención.


a[4::-1]

Ejemplo:

Python 2.6 (r26:66714, Dec 4 2008, 11:34:15) [GCC 4.0.1 (Apple Inc. build 5488)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> a = list(range(10)) >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> a[4:0:-1] [4, 3, 2, 1] >>> a[4::-1] [4, 3, 2, 1, 0] >>>

La razón es que el segundo término se interpreta como "while not index ==". Dejarlo afuera es "mientras el índice está dentro del rango".


Como dices, muy pocas personas entienden completamente todo lo que puedes hacer con el corte extendido, así que a menos que realmente necesites el rendimiento extra, lo haría de la manera "obvia":

rev_subset = reversed(data[start:stop])


[ A[b] for b in range(end,start,stride) ]

Más lento, sin embargo, puedes usar índices negativos, así que esto debería funcionar:

[ A[b] for b in range(9, -1, -1) ]

Me doy cuenta de que esto no está utilizando rebanadas, pero pensé que ofrecería la solución de todos modos si el uso de rodajas específicamente para obtener el resultado no es una prioridad.


Puedes usar un objeto slice(start, stop, step) , que es tal que

s=slice(start, stop, step) print a[s]

es lo mismo que

print a[start : stop : step]

y, además, puede establecer cualquiera de los argumentos a None para indicar nada entre los dos puntos. Entonces, en el caso que das, puedes usar slice(4, None, -1) .


Sé que esta es una vieja pregunta, pero en caso de que alguien como yo esté buscando respuestas:

>>> A[5-1::-1] [4, 3, 2, 1, 0] >>> A[4:1:-1] [4, 3, 2]


Es propenso a errores para cambiar la semántica de start y stop . Use None o -(len(a) + 1) lugar de 0 o -1 . La semántica no es arbitraria. Ver el artículo de Edsger W. Dijkstra "Por qué la numeración debería comenzar en cero" .

>>> a = range(10) >>> start, stop, step = 4, None, -1

O

>>> start, stop, step = 4, -(len(a) + 1), -1 >>> a[start:stop:step] [4, 3, 2, 1, 0]

O

>>> s = slice(start, stop, step) >>> a[s] [4, 3, 2, 1, 0]

Cuando s es una secuencia, los índices negativos en s[i:j:k] se tratan especialmente :

Si i o j es negativo, el índice es relativo al final de la cadena: len(s) + i o len(s) + j es sustituido. Pero tenga en cuenta que -0 sigue siendo 0 .

es por eso que len(range(10)[4:-1:-1]) == 0 porque es equivalente al range(10)[4:9:-1] .


Pero no puede usar eso si está almacenando sus índices en variables, por ejemplo.

¿Es esto satisfactorio?

>>> a = range(10) >>> start = 0 >>> end = 4 >>> a[4:start-1 if start > 0 else None:-1] [4, 3, 2, 1, 0]