Pregunta

Oso conmigo mientras me explica mi pregunta. Salte al rubro negrita si ya entiende extendida indexación lista rebanada.

En Python, puede listas de índices usando la notación de rebanada. He aquí un ejemplo:

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

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

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

también Se deja que el paso a ser negativo, lo que significa 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 para disminuir los índices de inicio y finalización:

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

¿Qué pasó? Se interpretar -1 como en el final de la matriz, no al principio. Sé que se puede lograr esto de la siguiente manera:

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

Pero no se puede utilizar esto en todos los casos. Por ejemplo, en un método que ha sido superado los índices.

Mi pregunta es:

¿Hay alguna buena manera de utilizar Pythonic rebanadas extendidas con pasos negativos y los índices de inicio y fin explícitas que incluye el primer elemento de una secuencia?

Esto es lo que he encontrado hasta el momento, pero parece poco satisfactoria.

>>> A[0:5][::-1]
[4, 3, 2, 1, 0]
¿Fue útil?

Solución 2

Ok, creo que esto es probablemente lo mejor que voy a conseguirlo. Gracias a Abgan por despertar la idea. Esto se basa en el hecho de que hay No hay una rebanada es tratado como si fuera un parámetro que falta. Alguien tiene algo mejor?

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

editar: comprobar si hay start==-1, no 0

Esto todavía no es ideal, ya que está golpeando fuertemente el comportamiento habitual de -1. Parece que el problema aquí es la superposición de dos definiciones de lo que se supone que suceda. El que gane se lleva invocaciones de otro modo válidos en busca de la otra intención.

Otros consejos

Es propenso a errores para cambiar la semántica de start y stop. Utilice None o -(len(a) + 1) en lugar de 0 o -1. La semántica no es arbitraria. Ver de Edsger Dijkstra artículo "¿Por qué la numeración debe 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 de los índices negativos en s[i:j:k] son especialmente tratado :

  

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

es por eso len(range(10)[4:-1:-1]) == 0 porque equivale a range(10)[4:9:-1].

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

Más lento, sin embargo se puede utilizar índices negativos, por lo que este debe trabajar:

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

Soy consciente de que no está utilizando rodajas, pero pensé que iba a ofrecer la solución de todos modos si se utiliza rebanadas específicamente para conseguir el resultado no es una prioridad.

Creo que el siguiente no le 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? : -)

  

Pero no se puede usar que si usted es   el almacenamiento de sus índices en las variables de   ejemplo.

Es esto satisfactoria?

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

Como se dice muy pocas personas entienden completamente todo lo que se puede hacer con rebanar extendida, así que a menos que realmente necesita la capacidad que lo haría el camino "obvio":

rev_subset = reversed(data[start:stop])

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 "mientras no índice ==". Dejando a cabo es "mientras que el índice de rango".

Sé que esto es una cuestión de edad, pero en caso de que alguien como yo, está en busca de respuestas:

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

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

Puede utilizar un objeto slice(start, stop, step), que es tal que

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

es el mismo que

print a[start : stop : step]

y, por otra parte, puede configurar cualquiera de los argumentos a None para indicar nada entre los dos puntos. Así, en el caso que se da, se puede utilizar slice(4, None, -1).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top