Entendiendo la notación de la porción

Necesito una buena explicación (las referencias son una ventaja) en la notación de corte de Python.

Para mí, esta notación necesita un poco de recuperación.

Parece extremadamente poderoso, pero no he logrado entenderlo.

Es bastante simple en realidad:

a[start:stop] # items start through stop-1 a[start:] # items start through the rest of the array a[:stop] # items from the beginning through stop-1 a[:] # a copy of the whole array 

También está el valor de step , que se puede utilizar con cualquiera de los anteriores:

 a[start:stop:step] # start through not past stop, by step 

El punto clave a recordar es que :stop valor de :stop representa el primer valor que no está en el sector seleccionado. Por lo tanto, la diferencia entre stop e start es el número de elementos seleccionados (si el step es 1, el valor predeterminado).

La otra característica es que start o stop puede ser un número negativo , lo que significa que cuenta desde el final de la matriz en lugar del principio. Asi que:

 a[-1] # last item in the array a[-2:] # last two items in the array a[:-2] # everything except the last two items 

Del mismo modo, el step puede ser un número negativo:

 a[::-1] # all items in the array, reversed a[1::-1] # the first two items, reversed a[:-3:-1] # the last two items, reversed a[-3::-1] # everything except the last two items, reversed 

Python es amable con el progtwigdor si hay menos elementos de los que pide. Por ejemplo, si solicita a[:-2] y solo contiene un elemento, obtiene una lista vacía en lugar de un error. A veces, prefiere el error, por lo que debe tener en cuenta que esto puede suceder.

Relación al objeto slice()

El operador de segmentación [] se está utilizando en realidad en el código anterior con un objeto slice() utilizando la notación : (que solo es válida dentro de [] ), es decir:

 a[start:stop:step] 

es equivalente a:

 a[slice(start, stop, step)] 

Los objetos de sector también se comportan de forma ligeramente diferente según el número de argumentos, de manera similar al range() , es decir, se admiten tanto el slice(stop) como el slice(start, stop[, step]) . Para omitir la especificación de un argumento dado, se podría usar None , de modo que, por ejemplo, a[start:] es equivalente a a[slice(start, None)] o a[::-1] es equivalente a a[slice(None, None, -1)] .

Si bien la notación basada en : es muy útil para el corte simple, el uso explícito de los objetos slice() simplifica la generación programática del corte.

El tutorial de Python habla sobre esto (desplácese hacia abajo un poco hasta que llegue a la parte sobre el corte).

El diagtwig artístico ASCII también es útil para recordar cómo funcionan los cortes:

  +---+---+---+---+---+---+ | P | y | t | h | o | n | +---+---+---+---+---+---+ 0 1 2 3 4 5 6 -6 -5 -4 -3 -2 -1 

Una forma de recordar cómo funcionan los cortes es pensar que los índices apuntan entre los caracteres, con el borde izquierdo del primer carácter numerado 0. Luego, el borde derecho del último carácter de una cadena de n caracteres tiene un índice n .

Enumerando las posibilidades permitidas por la gramática:

 >>> seq[:] # [seq[0], seq[1], ..., seq[-1] ] >>> seq[low:] # [seq[low], seq[low+1], ..., seq[-1] ] >>> seq[:high] # [seq[0], seq[1], ..., seq[high-1]] >>> seq[low:high] # [seq[low], seq[low+1], ..., seq[high-1]] >>> seq[::stride] # [seq[0], seq[stride], ..., seq[-1] ] >>> seq[low::stride] # [seq[low], seq[low+stride], ..., seq[-1] ] >>> seq[:high:stride] # [seq[0], seq[stride], ..., seq[high-1]] >>> seq[low:high:stride] # [seq[low], seq[low+stride], ..., seq[high-1]] 

Por supuesto, si (high-low)%stride != 0 , el punto final será un poco más bajo que high-1 .

Si stride es negativa, el orden se cambia un poco ya que estamos haciendo una cuenta regresiva:

 >>> seq[::-stride] # [seq[-1], seq[-1-stride], ..., seq[0] ] >>> seq[high::-stride] # [seq[high], seq[high-stride], ..., seq[0] ] >>> seq[:low:-stride] # [seq[-1], seq[-1-stride], ..., seq[low+1]] >>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]] 

El corte extendido (con comas y puntos suspensivos) se usa principalmente solo por estructuras de datos especiales (como NumPy); Las secuencias básicas no las soportan.

 >>> class slicee: ... def __getitem__(self, item): ... return `item` ... >>> slicee()[0, 1:2, ::5, ...] '(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)' 

Las respuestas anteriores no discuten la asignación de sectores. Para comprender la asignación de segmentos, es útil agregar otro concepto al arte ASCII:

  +---+---+---+---+---+---+ | P | y | t | h | o | n | +---+---+---+---+---+---+ Slice position: 0 1 2 3 4 5 6 Index position: 0 1 2 3 4 5 >>> p = ['P','y','t','h','o','n'] # Why the two sets of numbers: # indexing gives items, not lists >>> p[0] 'P' >>> p[5] 'n' # Slicing gives lists >>> p[0:1] ['P'] >>> p[0:2] ['P','y'] 

Una heurística es, para una porción de cero a n, piense: “cero es el comienzo, comience por el principio y tome n elementos en una lista”.

 >>> p[5] # the last of six items, indexed from zero 'n' >>> p[0:5] # does NOT include the last item! ['P','y','t','h','o'] >>> p[0:6] # not p[0:5]!!! ['P','y','t','h','o','n'] 

Otra heurística es: “para cualquier sector, reemplace el inicio por cero, aplique el método anterior para obtener el final de la lista, luego cuente el primer número para recortar los elementos del principio”

 >>> p[0:4] # Start at the beginning and count out 4 items ['P','y','t','h'] >>> p[1:4] # Take one item off the front ['y','t','h'] >>> p[2:4] # Take two items off the front ['t','h'] # etc. 

La primera regla de la asignación de división es que, dado que la segmentación devuelve una lista, la asignación de división requiere una lista (u otro iterable):

 >>> p[2:3] ['t'] >>> p[2:3] = ['T'] >>> p ['P','y','T','h','o','n'] >>> p[2:3] = 't' Traceback (most recent call last): File "", line 1, in  TypeError: can only assign an iterable 

La segunda regla de la asignación de sectores, que también puede ver arriba, es que cualquier parte de la lista se devuelve mediante la indexación de segmentos, que es la misma parte que se modifica por la asignación de segmentos:

 >>> p[2:4] ['T','h'] >>> p[2:4] = ['t','r'] >>> p ['P','y','t','r','o','n'] 

La tercera regla de asignación de segmentos es que la lista asignada (iterable) no tiene que tener la misma longitud; la porción indexada simplemente se corta y se reemplaza en masa por lo que se asigna:

 >>> p = ['P','y','t','h','o','n'] # Start over >>> p[2:4] = ['s','p','a','m'] >>> p ['P','y','s','p','a','m','o','n'] 

La parte más difícil de acostumbrarse es la asignación a segmentos vacíos. Usando los heurísticos 1 y 2 es fácil hacer que tu cabeza esté alrededor del índice de una porción vacía:

 >>> p = ['P','y','t','h','o','n'] >>> p[0:4] ['P','y','t','h'] >>> p[1:4] ['y','t','h'] >>> p[2:4] ['t','h'] >>> p[3:4] ['h'] >>> p[4:4] [] 

Y luego, una vez que haya visto eso, la asignación de división a la división vacía también tiene sentido:

 >>> p = ['P','y','t','h','o','n'] >>> p[2:4] = ['x','y'] # Assigned list is same length as slice >>> p ['P','y','x','y','o','n'] # Result is same length >>> p = ['P','y','t','h','o','n'] >>> p[3:4] = ['x','y'] # Assigned list is longer than slice >>> p ['P','y','t','x','y','o','n'] # The result is longer >>> p = ['P','y','t','h','o','n'] >>> p[4:4] = ['x','y'] >>> p ['P','y','t','h','x','y','o','n'] # The result is longer still 

Tenga en cuenta que, dado que no estamos cambiando el segundo número de la división (4), los elementos insertados siempre se astackn contra la ‘o’, incluso cuando estamos asignando la división vacía. Por lo tanto, la posición para la asignación de división vacía es la extensión lógica de las posiciones para las asignaciones de división no vacía.

Retrocediendo un poco, ¿qué sucede cuando continúas con nuestra procesión de contar el inicio de la porción?

 >>> p = ['P','y','t','h','o','n'] >>> p[0:4] ['P','y','t','h'] >>> p[1:4] ['y','t','h'] >>> p[2:4] ['t','h'] >>> p[3:4] ['h'] >>> p[4:4] [] >>> p[5:4] [] >>> p[6:4] [] 

Con rebanar, una vez que hayas terminado, has terminado; no comienza a cortar hacia atrás. En Python no obtienes zancadas negativas a menos que las pidas explícitamente usando un número negativo.

 >>> p[5:3:-1] ['n','o'] 

Hay algunas consecuencias extrañas en la regla de “una vez que hayas terminado, hayas terminado”:

 >>> p[4:4] [] >>> p[5:4] [] >>> p[6:4] [] >>> p[6] Traceback (most recent call last): File "", line 1, in  IndexError: list index out of range 

De hecho, en comparación con la indexación, el corte de Python es extrañamente a prueba de errores:

 >>> p[100:200] [] >>> p[int(2e99):int(1e99)] [] 

Esto puede ser útil a veces, pero también puede llevar a un comportamiento algo extraño:

 >>> p ['P', 'y', 't', 'h', 'o', 'n'] >>> p[int(2e99):int(1e99)] = ['p','o','w','e','r'] >>> p ['P', 'y', 't', 'h', 'o', 'n', 'p', 'o', 'w', 'e', 'r'] 

Dependiendo de tu aplicación, eso podría … o no … ¡ser lo que esperabas allí!


A continuación se muestra el texto de mi respuesta original. Ha sido útil para muchas personas, así que no quise borrarlo.

 >>> r=[1,2,3,4] >>> r[1:1] [] >>> r[1:1]=[9,8] >>> r [1, 9, 8, 2, 3, 4] >>> r[1:1]=['blah'] >>> r [1, 'blah', 9, 8, 2, 3, 4] 

Esto también puede aclarar la diferencia entre el corte y la indexación.

Explique la notación de corte de Python.

En resumen, los dos puntos (:) en la notación de subíndices ( subscriptable[subscriptarg] ) hacen notación de segmento, que tiene los argumentos opcionales, start , stop , step :

 sliceable[start:stop:step] 

El corte de Python es una forma computacionalmente rápida de acceder metódicamente a partes de sus datos. En mi opinión, para ser incluso un progtwigdor de Python intermedio, es un aspecto del lenguaje con el que es necesario estar familiarizado.

Definiciones importantes

Para empezar, definamos algunos términos:

inicio: el índice de inicio de la división, incluirá el elemento en este índice a menos que sea el mismo que detener , el valor predeterminado es 0, es decir, el primer índice. Si es negativo, significa iniciar n elementos desde el final.

detener: el índice final de la división, no incluye el elemento en este índice, la longitud predeterminada de la secuencia se divide, es decir, hasta e incluyendo el final.

paso: la cantidad en la que aumenta el índice, el valor predeterminado es 1. Si es negativo, está rebanando lo iterable a la inversa.

Cómo funciona la indexación

Puedes hacer cualquiera de estos números positivos o negativos. El significado de los números positivos es sencillo, pero para los números negativos, al igual que los índices en Python, contamos hacia atrás desde el final para el inicio y el final , y para el paso , simplemente disminuimos el índice. Este ejemplo es del tutorial de la documentación , pero lo he modificado ligeramente para indicar a qué elemento en una secuencia se refiere cada índice:

  +---+---+---+---+---+---+ | P | y | t | h | o | n | +---+---+---+---+---+---+ 0 1 2 3 4 5 -6 -5 -4 -3 -2 -1 

Cómo funciona el rebanado

Para usar la notación de división con una secuencia que la admita, debe incluir al menos un signo de dos puntos entre los corchetes que siguen la secuencia (que implementa el método __getitem__ de la secuencia, de acuerdo con el modelo de datos de Python ).

La notación de la rebanada funciona así:

 sequence[start:stop:step] 

Y recuerde que hay valores predeterminados para inicio , parada y paso , de modo que para acceder a los valores predeterminados, simplemente omita el argumento.

La notación de división para obtener los últimos nueve elementos de una lista (o cualquier otra secuencia que la admita, como una cadena) se vería así:

 my_list[-9:] 

Cuando veo esto, leo la parte entre corchetes como “9 desde el final, hasta el final”. (En realidad, lo abrevio mentalmente como “-9, en”)

Explicación:

La notación completa es

 my_list[-9:None:None] 

y para sustituir los valores predeterminados (en realidad, cuando el step es negativo, el valor predeterminado de la stop es -len(my_list) - 1 , entonces None para detener realmente significa que va a cualquier paso final que lo lleve a):

 my_list[-9:len(my_list):1] 

Los dos puntos , : , es lo que le dice a Python que le está dando una porción y no un índice regular. Es por eso que la forma idiomática de hacer una copia superficial de las listas en Python 2 es

 list_copy = sequence[:] 

Y limpiarlos es con:

 del my_list[:] 

(Python 3 obtiene un método list.copy y list.clear ).

Cuando el step es negativo, los valores predeterminados de start y stop cambian

De forma predeterminada, cuando el argumento de step está vacío (o None ), se asigna a +1 .

Sin embargo, puede pasar un entero negativo, y la lista (o la mayoría de los otros resúmenes estándar) se dividirá desde el final hasta el principio.

Por lo tanto, un segmento negativo cambiará los valores predeterminados para start y stop .

Confirmando esto en la fuente.

Me gusta animar a los usuarios a leer la fuente, así como la documentación. El código fuente de los objetos de división y esta lógica se encuentran aquí . Primero determinamos si el step es negativo:

  step_is_negative = step_sign < 0; 

Si es así, el límite inferior es -1 lo que significa que dividimos todo el camino hasta e incluyendo el principio, y el límite superior es la longitud menos 1, lo que significa que comenzamos por el final. (Tenga en cuenta que la semántica de este -1 es diferente de un -1 que los usuarios pueden pasar índices en Python que indican el último elemento).

 if (step_is_negative) { lower = PyLong_FromLong(-1L); if (lower == NULL) goto error; upper = PyNumber_Add(length, lower); if (upper == NULL) goto error; } 

De lo contrario, el step es positivo, y el límite inferior será cero y el límite superior (que vamos hasta pero sin incluir) la longitud de la lista dividida.

 else { lower = _PyLong_Zero; Py_INCREF(lower); upper = length; Py_INCREF(upper); } 

Entonces, es posible que tengamos que aplicar los valores predeterminados para el start y la stop ; el valor predeterminado para el start se calcula como el límite superior cuando el step es negativo:

 if (self->start == Py_None) { start = step_is_negative ? upper : lower; Py_INCREF(start); } 

y stop , el límite inferior:

 if (self->stop == Py_None) { stop = step_is_negative ? lower : upper; Py_INCREF(stop); } 

¡Dale a tus cortes un nombre descriptivo!

Puede que le resulte útil separar la formación de la porción de pasarla a la list.__getitem__ método list.__getitem__ ( eso es lo que hacen los corchetes ). Incluso si no es nuevo en esto, mantiene su código más legible para que otras personas que tengan que leerlo puedan entender más fácilmente lo que está haciendo.

Sin embargo, no puede simplemente asignar algunos enteros separados por dos puntos a una variable. Necesitas usar el objeto slice:

 last_nine_slice = slice(-9, None) 

El segundo argumento, None , es obligatorio, por lo que el primer argumento se interpreta como el argumento de start contrario sería el argumento de stop .

A continuación, puede pasar el objeto de división a su secuencia:

 >>> list(range(100))[last_nine_slice] [91, 92, 93, 94, 95, 96, 97, 98, 99] 

Es interesante que los rangos también toman rebanadas:

 >>> range(100)[last_nine_slice] range(91, 100) 

Consideraciones de memoria:

Dado que las listas de segmentos de Python crean nuevos objetos en la memoria, otra función importante a tener en cuenta es itertools.islice . Por lo general, querrá iterar sobre una porción, no solo hacer que se cree estáticamente en la memoria. islice es perfecto para esto. Una advertencia, no admite argumentos negativos para start , stop o step , por lo que si ese es un problema, es posible que necesite calcular índices o revertir el iterable por adelantado.

 length = 100 last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1) list_last_nine = list(last_nine_iter) 

y ahora:

 >>> list_last_nine [91, 92, 93, 94, 95, 96, 97, 98, 99] 

El hecho de que las porciones de la lista hagan una copia es una característica de las listas. Si está rebanando objetos avanzados como Pandas DataFrame, puede devolver una vista en el original, y no una copia.

Y un par de cosas que no eran inmediatamente obvias para mí cuando vi por primera vez la syntax de corte:

 >>> x = [1,2,3,4,5,6] >>> x[::-1] [6,5,4,3,2,1] 

Una manera fácil de revertir secuencias!

Y si quisiera, por alguna razón, cada segundo elemento en la secuencia invertida:

 >>> x = [1,2,3,4,5,6] >>> x[::-2] [6,4,2] 

En Python 2.7

Rebanar en Python

 [a:b:c] len = length of string, tuple or list c -- default is +1. The sign of c indicates forward or backward, absolute value of c indicates steps. Default is forward with step size 1. Positive means forward, negative means backward. a -- When c is positive or blank, default is 0. When c is negative, default is -1. b -- When c is positive or blank, default is len. When c is negative, default is -(len+1). 

Comprender la asignación del índice es muy importante.

 In forward direction, starts at 0 and ends at len-1 In backward direction, starts at -1 and ends at -len 

Cuando dice [a: b: c], está diciendo que dependiendo del signo de c (adelante o atrás), comience en a y termine en b (excluyendo el elemento en el bth index). Utilice la regla de indexación anterior y recuerde que solo encontrará elementos en este rango:

 -len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1 

Pero este rango continúa infinitamente en ambas direcciones:

 ...,-len -2 ,-len-1,-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1, len, len +1, len+2 , .... 

Por ejemplo:

  0 1 2 3 4 5 6 7 8 9 10 11 astring -9 -8 -7 -6 -5 -4 -3 -2 -1 

Si su elección de a, b, y c permite superponerse con el rango de arriba a medida que recorre las reglas para a, b, c de arriba, obtendrá una lista de elementos (que se toca durante el recorrido) o obtendrá una lista vacía.

Una última cosa: si a y b son iguales, entonces también obtienes una lista vacía:

 >>> l1 [2, 3, 4] >>> l1[:] [2, 3, 4] >>> l1[::-1] # a default is -1 , b default is -(len+1) [4, 3, 2] >>> l1[:-4:-1] # a default is -1 [4, 3, 2] >>> l1[:-3:-1] # a default is -1 [4, 3] >>> l1[::] # c default is +1, so a default is 0, b default is len [2, 3, 4] >>> l1[::-1] # c is -1 , so a default is -1 and b default is -(len+1) [4, 3, 2] >>> l1[-100:-200:-1] # Interesting [] >>> l1[-1:-200:-1] # Interesting [4, 3, 2] >>> l1[-1:-1:1] [] >>> l1[-1:5:1] # Interesting [4] >>> l1[1:-7:1] [] >>> l1[1:-7:-1] # Interesting [3, 2] >>> l1[:-2:-2] # a default is -1, stop(b) at -2 , step(c) by 2 in reverse direction [4] 

Encontré esta gran tabla en http://wiki.python.org/moin/MovingToPythonFromOtherLanguages

 Python indexes and slices for a six-element list. Indexes enumerate the elements, slices enumerate the spaces between the elements. Index from rear: -6 -5 -4 -3 -2 -1 a=[0,1,2,3,4,5] a[1:]==[1,2,3,4,5] Index from front: 0 1 2 3 4 5 len(a)==6 a[:5]==[0,1,2,3,4] +---+---+---+---+---+---+ a[0]==0 a[:-2]==[0,1,2,3] | a | b | c | d | e | f | a[5]==5 a[1:2]==[1] +---+---+---+---+---+---+ a[-1]==5 a[1:-1]==[1,2,3,4] Slice from front: : 1 2 3 4 5 : a[-2]==4 Slice from rear: : -5 -4 -3 -2 -1 : b=a[:] b==[0,1,2,3,4,5] (shallow copy of a) 

Después de usarlo un poco, me doy cuenta de que la descripción más simple es que es exactamente lo mismo que los argumentos en un bucle for

 (from:to:step) 

Cualquiera de ellos es opcional:

 (:to:step) (from::step) (from:to) 

Entonces, la indexación negativa solo necesita que usted agregue la longitud de la cadena a los índices negativos para entenderla.

Esto funciona para mí de todos modos …

Me resulta más fácil recordar cómo funciona, y luego puedo encontrar una combinación específica de inicio / parada / paso.

Es instructivo entender el range() primero:

 def range(start=0, stop, step=1): # Illegal syntax, but that's the effect i = start while (i < stop if step > 0 else i > stop): yield i i += step 

Comience desde el start , aumente por step , no llegue a stop . Muy simple.

Lo que hay que recordar sobre el paso negativo es que stop siempre es el extremo excluido, ya sea más alto o más bajo. Si desea la misma división en orden opuesto, es mucho más limpio hacer la reversión por separado: por ejemplo, 'abcde'[1:-2][::-1] corta una charca de la izquierda, dos de la derecha y luego retrocede. (Ver también reversed() .)

La división de secuencias es la misma, excepto que primero normaliza los índices negativos, y nunca puede salir de la secuencia:

TODO : El código siguiente tenía un error con “nunca salir de la secuencia” cuando abs (paso)> 1; Creo que lo parché para que sea correcto, pero es difícil de entender.

 def this_is_how_slicing_works(seq, start=None, stop=None, step=1): if start is None: start = (0 if step > 0 else len(seq)-1) elif start < 0: start += len(seq) if not 0 <= start < len(seq): # clip if still outside bounds start = (0 if step > 0 else len(seq)-1) if stop is None: stop = (len(seq) if step > 0 else -1) # really -1, not last element elif stop < 0: stop += len(seq) for i in range(start, stop, step): if 0 <= i < len(seq): yield seq[i] 

No se preocupe por los detalles de " is None , solo recuerde que omitir start y / o stop siempre hace lo correcto para darle toda la secuencia.

La normalización de los índices negativos primero permite que el inicio y / o la parada se cuenten desde el final de forma independiente: 'abcde'[1:-2] == 'abcde'[1:3] == 'bc' pesar del range(1,-2) == [] . La normalización a veces se considera "módulo de la longitud", pero tenga en cuenta que agrega la longitud solo una vez: por ejemplo, 'abcde'[-53:42] es solo la cadena completa.

 Index: ------------> 0 1 2 3 4 +---+---+---+---+---+ | a | b | c | d | e | +---+---+---+---+---+ 0 -4 -3 -2 -1 <------------ Slice: <---------------| |---------------> : 1 2 3 4 : +---+---+---+---+---+ | a | b | c | d | e | +---+---+---+---+---+ : -4 -3 -2 -1 : |---------------> <---------------| 

Espero que esto te ayude a modelar la lista en Python.

Referencia: http://wiki.python.org/moin/MovingToPythonFromOtherLanguages

Utilizo el método de “un punto de índice entre elementos” para pensarlo, pero una forma de describirlo que a veces ayuda a otros a obtenerlo es esta:

 mylist[X:Y] 

X es el índice del primer elemento que desea.
Y es el índice del primer elemento que no desea.

Notación de corte de Python:

 a[start:end:step] 
  • Para el start y el end , los valores negativos se interpretan como relativos al final de la secuencia.
  • Los índices positivos para el end indican la posición después del último elemento que se incluirá.
  • Los valores en blanco están predeterminados de la siguiente manera: [+0:-0:1] .
  • Usar un paso negativo invierte la interpretación de start y end

La notación se extiende a matrices (numpy) y matrices multidimensionales. Por ejemplo, para cortar columnas enteras puede usar:

 m[::,0:2:] ## slice the first two columns 

Los segmentos contienen referencias, no copias, de los elementos de la matriz. Si desea hacer una copia separada de una matriz, puede usar deepcopy() .

Así es como enseño las rebanadas a los novatos:

Entendiendo la diferencia entre indexación y corte:

Wiki Python tiene esta increíble imagen que distingue claramente la indexación y el corte.

introduzca la descripción de la imagen aquí

Es una lista con 6 elementos en ella. Para comprender mejor cómo rebanar, considere esa lista como un conjunto de seis cuadros colocados juntos. Cada caja tiene un alfabeto en ella.

La indexación es como tratar con los contenidos de la caja. Puede consultar el contenido de cualquier casilla. Pero no puedes marcar el contenido de varias casillas a la vez. Incluso puede reemplazar el contenido de la caja. Pero no puede colocar 2 bolas en 1 caja o reemplazar 2 bolas a la vez.

 In [122]: alpha = ['a', 'b', 'c', 'd', 'e', 'f'] In [123]: alpha Out[123]: ['a', 'b', 'c', 'd', 'e', 'f'] In [124]: alpha[0] Out[124]: 'a' In [127]: alpha[0] = 'A' In [128]: alpha Out[128]: ['A', 'b', 'c', 'd', 'e', 'f'] In [129]: alpha[0,1] --------------------------------------------------------------------------- TypeError Traceback (most recent call last)  in () ----> 1 alpha[0,1] TypeError: list indices must be integers, not tuple 

Cortar es como tratar con cajas en sí. Puede recoger la primera caja y colocarla en otra mesa. Para recoger la caja, todo lo que necesita saber es la posición de inicio y finalización de la caja.

Incluso puede recoger las primeras 3 cajas o las 2 últimas cajas o todas las cajas entre 1 y 4. Por lo tanto, puede seleccionar cualquier conjunto de cajas si sabe el principio y el final. Estas posiciones se llaman posiciones de inicio y parada.

Lo interesante es que puedes reemplazar múltiples cajas a la vez. También puedes colocar múltiples casillas donde quieras.

 In [130]: alpha[0:1] Out[130]: ['A'] In [131]: alpha[0:1] = 'a' In [132]: alpha Out[132]: ['a', 'b', 'c', 'd', 'e', 'f'] In [133]: alpha[0:2] = ['A', 'B'] In [134]: alpha Out[134]: ['A', 'B', 'c', 'd', 'e', 'f'] In [135]: alpha[2:2] = ['x', 'xx'] In [136]: alpha Out[136]: ['A', 'B', 'x', 'xx', 'c', 'd', 'e', 'f'] 

Cortando Con Paso:

Hasta ahora has recogido cajas continuamente. Pero algunas veces necesitas recoger discretamente. Por ejemplo, puede recoger cada segundo cuadro. Incluso puedes recoger cada tercer cuadro desde el final. Este valor se llama tamaño de paso. Esto representa la brecha entre sus recolecciones sucesivas. El tamaño del paso debe ser positivo si está seleccionando cuadros desde el principio hasta el final y viceversa.

 In [137]: alpha = ['a', 'b', 'c', 'd', 'e', 'f'] In [142]: alpha[1:5:2] Out[142]: ['b', 'd'] In [143]: alpha[-1:-5:-2] Out[143]: ['f', 'd'] In [144]: alpha[1:5:-2] Out[144]: [] In [145]: alpha[-1:-5:2] Out[145]: [] 

Cómo Python descubre los parámetros que faltan:

Al rebanar si omite algún parámetro, Python intenta resolverlo automáticamente.

Si verifica el código fuente de CPython, encontrará una función llamada PySlice_GetIndicesEx que calcula los índices en una porción para cualquier parámetro dado. Aquí está el código equivalente lógico en Python.

Esta función toma un objeto de Python y parámetros opcionales para segmentar y devuelve la longitud de inicio, parada, paso y división para la división solicitada.

 def py_slice_get_indices_ex(obj, start=None, stop=None, step=None): length = len(obj) if step is None: step = 1 if step == 0: raise Exception("Step cannot be zero.") if start is None: start = 0 if step > 0 else length - 1 else: if start < 0: start += length if start < 0: start = 0 if step > 0 else -1 if start >= length: start = length if step > 0 else length - 1 if stop is None: stop = length if step > 0 else -1 else: if stop < 0: stop += length if stop < 0: stop = 0 if step > 0 else -1 if stop >= length: stop = length if step > 0 else length - 1 if (step < 0 and stop >= start) or (step > 0 and start >= stop): slice_length = 0 elif step < 0: slice_length = (stop - start + 1)/(step) + 1 else: slice_length = (stop - start - 1)/(step) + 1 return (start, stop, step, slice_length) 

Esta es la inteligencia que está presente detrás de las rebanadas. Como Python tiene una función incorporada llamada slice, puede pasar algunos parámetros y verificar qué tan inteligente calcula los parámetros faltantes.

 In [21]: alpha = ['a', 'b', 'c', 'd', 'e', 'f'] In [22]: s = slice(None, None, None) In [23]: s Out[23]: slice(None, None, None) In [24]: s.indices(len(alpha)) Out[24]: (0, 6, 1) In [25]: range(*s.indices(len(alpha))) Out[25]: [0, 1, 2, 3, 4, 5] In [26]: s = slice(None, None, -1) In [27]: range(*s.indices(len(alpha))) Out[27]: [5, 4, 3, 2, 1, 0] In [28]: s = slice(None, 3, -1) In [29]: range(*s.indices(len(alpha))) Out[29]: [5, 4] 

Nota: esta publicación está originalmente escrita en mi blog http://www.avilpage.com/2015/03/a-slice-of-python-intelligence-behind.html

Esto es solo para información adicional … Considere la lista a continuación

 >>> l=[12,23,345,456,67,7,945,467] 

Algunos otros trucos para revertir la lista:

 >>> l[len(l):-len(l)-1:-1] [467, 945, 7, 67, 456, 345, 23, 12] >>> l[:-len(l)-1:-1] [467, 945, 7, 67, 456, 345, 23, 12] >>> l[len(l)::-1] [467, 945, 7, 67, 456, 345, 23, 12] >>> l[::-1] [467, 945, 7, 67, 456, 345, 23, 12] >>> l[-1:-len(l)-1:-1] [467, 945, 7, 67, 456, 345, 23, 12] 

Vea la respuesta de abc arriba

También puede usar la asignación de división para eliminar uno o más elementos de una lista:

 r = [1, 'blah', 9, 8, 2, 3, 4] >>> r[1:4] = [] >>> r [1, 2, 3, 4] 

Como regla general, escribir código con una gran cantidad de valores de índice codificados en el código conduce a un problema de legibilidad y mantenimiento. Por ejemplo, si regresa al código un año después, lo verá y se preguntará qué pensaba cuando lo escribió. La solución mostrada es simplemente una forma de indicar más claramente lo que realmente está haciendo su código. En general, la división incorporada () crea un objeto de división que se puede utilizar en cualquier lugar donde se permita una división. Por ejemplo:

 >>> items = [0, 1, 2, 3, 4, 5, 6] >>> a = slice(2, 4) >>> items[2:4] [2, 3] >>> items[a] [2, 3] >>> items[a] = [10,11] >>> items [0, 1, 10, 11, 4, 5, 6] >>> del items[a] >>> items [0, 1, 4, 5, 6] 

Si tiene una instancia de división, puede obtener más información sobre ella mirando sus atributos s.start, s.stop y s.step, respectivamente. Por ejemplo:

 >>> a = slice(10, 50, 2) >>> a.start 10 >>> a.stop 50 >>> a.step 2 >>> 

1. Notación de la rebanada

Para hacerlo simple, recuerde que la sección tiene solo una forma :

 s[start:end:step] 

Y así es como funciona:

  • s : un objeto que puede ser cortado
  • start : primer índice para iniciar la iteración
  • end : último índice, NOTA que el índice end no se incluirá en la porción resultante
  • step : elegir elemento cada índice de step

Otra cosa importante: ¡ todo start , end , step puede ser omitido! Y si se omiten, se utilizará su valor predeterminado: 0 , len(s) , 1 consecuencia.

Así que las posibles variaciones son:

 # mostly used variations s[start:end] s[start:] s[:end] # step related variations s[:end:step] s[start::step] s[::step] # make a copy s[:] 

NOTE: If start>=end (considering only when step>0 ), python will return a empty slice [] .

2. Pitfalls

The above part explains the core features on how slice works, it will work on most occasions. However there can be pitfalls you should watch out, and this part explains them.

Negative indexes

The very first thing confuses python learners is that index can be negative! Don’t panic: negative index means count from backwards.

Por ejemplo:

 s[-5:] # start at the 5th index from the end of array, # thus returns the last 5 elements s[:-5] # start at index 0, end until the 5th index from end of array, # thus returns s[0:len(s)-5] 

Negative step

Make things more confusing is that step can be negative too!

Negative step means iterate the array backwards: from end to start, with end index included, and start index excluded from result.

NOTE : when step is negative, the default value for start to len(s) (while end does not equal to 0 , because s[::-1] contains s[0] ). Por ejemplo:

 s[::-1] # reversed slice s[len(s)::-1] # same as above, reversed slice s[0:len(s):-1] # empty list 

Out of range error?

Be surprised: slice does not raise IndexError when index is out of range!

If the index is out of range, python will try its best set the index to 0 or len(s) according to the situation. Por ejemplo:

 s[:len(s)+5] # same as s[:len(s)] s[-len(s)-5::] # same as s[0:] s[len(s)+5::-1] # same as s[len(s)::-1], same as s[::-1] 

3. Examples

Let’s finish this answer with examples explains everything we have discussed:

 # create our array for demonstration In [1]: s = [i for i in range(10)] In [2]: s Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] In [3]: s[2:] # from index 2 to last index Out[3]: [2, 3, 4, 5, 6, 7, 8, 9] In [4]: s[:8] # from index 0 up to index 8 Out[4]: [0, 1, 2, 3, 4, 5, 6, 7] In [5]: s[4:7] # from index 4(included) up to index 7(excluded) Out[5]: [4, 5, 6] In [6]: s[:-2] # up to second last index(negative index) Out[6]: [0, 1, 2, 3, 4, 5, 6, 7] In [7]: s[-2:] # from second last index(negative index) Out[7]: [8, 9] In [8]: s[::-1] # from last to first in reverse order(negative step) Out[8]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] In [9]: s[::-2] # all odd numbers in reversed order Out[9]: [9, 7, 5, 3, 1] In [11]: s[-2::-2] # all even numbers in reversed order Out[11]: [8, 6, 4, 2, 0] In [12]: s[3:15] # end is out of range, python will set it to len(s) Out[12]: [3, 4, 5, 6, 7, 8, 9] In [14]: s[5:1] # start > end, return empty list Out[14]: [] In [15]: s[11] # access index 11(greater than len(s)) will raise IndexError --------------------------------------------------------------------------- IndexError Traceback (most recent call last)  in () ----> 1 s[11] IndexError: list index out of range 

The answers above don’t discuss multi-dimentional array slicing which is possible using the famous numpy package:

Slicing also apply to multi-dimentional arrays.

 # Here, a is a numpy array >>> a array([[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12]]) >>> a[:2,0:3:2] array([[1, 3], [5, 7]]) 

The “:2” before comma operates on the first dimension and the “0:3:2” after the comma operates on the second dimension.

 #!/usr/bin/env python def slicegraphical(s, lista): if len(s) > 9: print """Enter a string of maximum 9 characters, so the printig would looki nice""" return 0; # print " ", print ' '+'+---' * len(s) +'+' print ' ', for letter in s: print '| {}'.format(letter), print '|' print " ",; print '+---' * len(s) +'+' print " ", for letter in range(len(s) +1): print '{} '.format(letter), print "" for letter in range(-1*(len(s)), 0): print ' {}'.format(letter), print '' print '' for triada in lista: if len(triada) == 3: if triada[0]==None and triada[1] == None and triada[2] == None: # 000 print s+'[ : : ]' +' = ', s[triada[0]:triada[1]:triada[2]] elif triada[0] == None and triada[1] == None and triada[2] != None: # 001 print s+'[ : :{0:2d} ]'.format(triada[2], '','') +' = ', s[triada[0]:triada[1]:triada[2]] elif triada[0] == None and triada[1] != None and triada[2] == None: # 010 print s+'[ :{0:2d} : ]'.format(triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]] elif triada[0] == None and triada[1] != None and triada[2] != None: # 011 print s+'[ :{0:2d} :{1:2d} ]'.format(triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]] elif triada[0] != None and triada[1] == None and triada[2] == None: # 100 print s+'[{0:2d} : : ]'.format(triada[0]) +' = ', s[triada[0]:triada[1]:triada[2]] elif triada[0] != None and triada[1] == None and triada[2] != None: # 101 print s+'[{0:2d} : :{1:2d} ]'.format(triada[0], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]] elif triada[0] != None and triada[1] != None and triada[2] == None: # 110 print s+'[{0:2d} :{1:2d} : ]'.format(triada[0], triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]] elif triada[0] != None and triada[1] != None and triada[2] != None: # 111 print s+'[{0:2d} :{1:2d} :{2:2d} ]'.format(triada[0], triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]] elif len(triada) == 2: if triada[0] == None and triada[1] == None: # 00 print s+'[ : ] ' + ' = ', s[triada[0]:triada[1]] elif triada[0] == None and triada[1] != None: # 01 print s+'[ :{0:2d} ] '.format(triada[1]) + ' = ', s[triada[0]:triada[1]] elif triada[0] != None and triada[1] == None: # 10 print s+'[{0:2d} : ] '.format(triada[0]) + ' = ', s[triada[0]:triada[1]] elif triada[0] != None and triada[1] != None: # 11 print s+'[{0:2d} :{1:2d} ] '.format(triada[0],triada[1]) + ' = ', s[triada[0]:triada[1]] elif len(triada) == 1: print s+'[{0:2d} ] '.format(triada[0]) + ' = ', s[triada[0]] if __name__ == '__main__': # Change "s" to what ever string you like, make it 9 characters for # better representation. s = 'COMPUTERS' # add to this list different lists to experement with indexes # to represent ex. s[::], use s[None, None,None], otherwise you get an error # for s[2:] use s[2:None] lista = [[4,7],[2,5,2],[-5,1,-1],[4],[-4,-6,-1], [2,-3,1],[2,-3,-1], [None,None,-1],[-5,None],[-5,0,-1],[-5,None,-1],[-1,1,-2]] slicegraphical(s, lista) 

You can run this script and experiment with it, below is some samples that I got from the script.

  +---+---+---+---+---+---+---+---+---+ | C | O | M | P | U | T | E | R | S | +---+---+---+---+---+---+---+---+---+ 0 1 2 3 4 5 6 7 8 9 -9 -8 -7 -6 -5 -4 -3 -2 -1 COMPUTERS[ 4 : 7 ] = UTE COMPUTERS[ 2 : 5 : 2 ] = MU COMPUTERS[-5 : 1 :-1 ] = UPM COMPUTERS[ 4 ] = U COMPUTERS[-4 :-6 :-1 ] = TU COMPUTERS[ 2 :-3 : 1 ] = MPUT COMPUTERS[ 2 :-3 :-1 ] = COMPUTERS[ : :-1 ] = SRETUPMOC COMPUTERS[-5 : ] = UTERS COMPUTERS[-5 : 0 :-1 ] = UPMO COMPUTERS[-5 : :-1 ] = UPMOC COMPUTERS[-1 : 1 :-2 ] = SEUM [Finished in 0.9s] 

When using a negative step, notice that the answer is shifted to the right by 1.

My brain seems happy to accept that lst[start:end] contains the start -th item. I might even say that it is a ‘natural assumption’.

But occasionally a doubt creeps in and my brain asks for reassurance that it does not contain the end -th element.

In these moments I rely on this simple theorem:

 for any n, lst = lst[:n] + lst[n:] 

This pretty property tells me that lst[start:end] does not contain the end -th item because it is in lst[end:] .

Note that this theorem is true for any n at all. For example, you can check that

 lst = range(10) lst[:-42] + lst[-42:] == lst 

returns True .

In Python, the most basic form for slicing is the following:

l[start:end]

where l is some collection, start is an inclusive index and end is an exclusive index.

 In [1]: l = list(range(10)) In [2]: l[:5] # first five elements Out[2]: [0, 1, 2, 3, 4] In [3]: l[-5:] # last five elements Out[3]: [5, 6, 7, 8, 9] 

When slicing from start, you can omit the zero index, and when slicing to the end, you can omit the final index since it is redundant, so do not be verbose:

 In [5]: l[:3] == l[0:3] Out[5]: True In [6]: l[7:] == l[7:len(l)] Out[6]: True 

Negative integers are useful when doing offsets relative to the end of a collection:

 In [7]: l[:-1] # include all elements but the last one Out[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8] In [8]: l[-3:] # take the last 3 elements Out[8]: [7, 8, 9] 

It is possible to provide indices that are out of bounds when slicing such as:

 In [9]: l[:20] # 20 is out of index bounds, l[20] will raise an IndexError exception Out[9]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] In [11]: l[-20:] # -20 is out of index bounds, l[-20] will raise an IndexError exception Out[11]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Keep in mind that the result of slicing a collection is a whole new collection. In addition, when using slice notation in assignments, the length of the slice assignment do not need to be the same. The values before and after the assigned slice will be kept, and the collection will shrink or grow to contain the new values:

 In [16]: l[2:6] = list('abc') # assigning less elements than the ones contained in the sliced collection l[2:6] In [17]: l Out[17]: [0, 1, 'a', 'b', 'c', 6, 7, 8, 9] In [18]: l[2:5] = list('hello') # assigning more elements than the ones contained in the sliced collection l [2:5] In [19]: l Out[19]: [0, 1, 'h', 'e', 'l', 'l', 'o', 6, 7, 8, 9] 

If you omit the start and end index, you will make a copy of the collection:

 In [14]: l_copy = l[:] In [15]: l == l_copy and l is not l_copy Out[15]: True 

If the start and end indexes are omitted when performing an assignment operation, the entire content of the collection will be replaced with a copy of what is referenced:

 In [20]: l[:] = list('hello...') In [21]: l Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.'] 

Besides basic slicing, it is also possible to apply the following notation:

 l[start:end:step] 

where l is a collection, start is an inclusive index, end is an exclusive index, and step is a stride that can be used to take every nth item in l .

 In [22]: l = list(range(10)) In [23]: l[::2] # take the elements which indexes are even Out[23]: [0, 2, 4, 6, 8] In [24]: l[1::2] # take the elements which indexes are odd Out[24]: [1, 3, 5, 7, 9] 

Using step provides a useful trick to reverse a collection in Python:

 In [25]: l[::-1] Out[25]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 

It is also possible to use negative integers for step as the following example:

 In[28]: l[::-2] Out[28]: [9, 7, 5, 3, 1] 

However, using a negative value for step could become very confusing. Moreover, in order to be Pythonic, you should avoid using start , end , and step in a single slice. In case this is required, consider doing this in two assignments (one to slice, and the other to stride).

 In [29]: l = l[::2] # this step is for striding In [30]: l Out[30]: [0, 2, 4, 6, 8] In [31]: l = l[1:-1] # this step is for slicing In [32]: l Out[32]: [2, 4, 6] 

Most of the above answers clears about Slice notation. Extended indexing syntax used for slicing is aList[start:stop:step] basic examples are

introduzca la descripción de la imagen aquí :

More Slicing examples: 15 Extended Slices

The below is the example of index of a string

  +---+---+---+---+---+ | H | e | l | p | A | +---+---+---+---+---+ 0 1 2 3 4 5 -5 -4 -3 -2 -1 str="Name string" 

slicing example: [start:end:step]

 str[start:end] # items start through end-1 str[start:] # items start through the rest of the array str[:end] # items from the beginning through end-1 str[:] # a copy of the whole array 

Below is the example usage

 print str[0]=N print str[0:2]=Na print str[0:7]=Name st print str[0:7:2]=Nm t print str[0:-1:2]=Nm ti 

I want to add one Hello world example that explains the basics of slices for the very beginners. It helped me a lot.

Let’s have a list with six values ['P', 'Y', 'T', 'H', 'O', 'N'] :

 +---+---+---+---+---+---+ | P | Y | T | H | O | N | +---+---+---+---+---+---+ 0 1 2 3 4 5 

Now the simplest slices of that list are its sublists. The notation is [:] and the key is to read it like this:

 [ start cutting before this index : end cutting before this index ] 

Now if you make a slice [2:5] of the list above, this will happen:

  | | +---+---|---+---+---|---+ | P | Y | T | H | O | N | +---+---|---+---+---|---+ 0 1 | 2 3 4 | 5 

You made a cut before the element with index 2 and another cut before the element with index 5 . So the result will be a slice between those two cuts, a list ['T', 'H', 'O'] .

Hehehe, it is kind of strange to see myself trying to provide a better and simpler explanation after 2600+ votes on what’s been marked as the right answer from Grew Hewgill.

Here we go …

In my opinion, you will understand and memorize better the Python string slicing notation if you look at it the following way (read on).

Let’s work with the following string …

 azString = "abcdefghijklmnopqrstuvwxyz" 

For those who don’t know, you can create any substring from azString using the notation azString[x:y]

Coming from other programming languages, that’s when the common sense gets compromised. What are x and y?

I had to sit down and run several scenarios in my quest for a memorization technique that will help me remember what x and y are and help me slice strings properly at the first attempt.

My conclusion is that x and y should be seen as the boundary indexes that are surrounding the strings that we want to extra. So we should see the expression as azString[index1, index2] or even more clearer as azString[index_of_first_character, index_after_the_last_character] .

Here is an example visualization of that …

Letters abcdefghij ... ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ Indexes 0 1 2 3 4 5 6 7 8 9 ... | | cdefgh index1 index2

So all you have to do if to set index1 and index2 to the values that will surround the desired substring. For instance, to get the substring “cdefgh”, you can use azString[2:8] because the index on the left side of “c” is 2 and the one on the right size of “h” is 8.

Remember, we are setting the boundaries.

That trick works all the time and is easy to memorize.

Hopefuly this will help.

Slice :- snake appears near your foot. It moves from the invisible to the visible. Our vision reveals (like a slice) only a part of the world. similarly A Python slice extracts elements, based on a start and stop. We take slices on many types in Python. We specify an optional first index, an optional last index, and an optional step.

 values[1:3] Index 1 through index 3. values[2:-1] Index 2 through index one from last. values[:2] Start through index 2. values[2:] Index 2 through end. values[::2] Start through end, skipping ahead 2 places each time. 

you can get good examples at below link:- python slice notation example

If you feel negative indices in slicing is confusing, here’s very easy way to think about it: just replace negative index with len - index . So for example, replace -3 with len(list) - 3 .

The best way to illustrate what slicing does internally is just show it in code that implements this operation:

 def slice(list, start = None, end = None, step = 1): # take care of missing start/end parameters start = 0 if start is None else start end = len(list) if end is None else end # take care of negative start/end parameters start = len(list) + start if start < 0 else start end = len(list) + end if end < 0 else end # now just execute for-loop with start, end and step return [list[i] for i in range(start, end, step)] 

The basic slicing technique is to define the starting point, the stopping point, and the step size – also known as stride.

First, we will create a list of values to use in our slicing.

Create two lists to slice, the first is a numeric list from 1 to 9 (List A). The second is also a numeric list, from 0 to 9 (List B)

 A = list(range(1,10,1)) # start,stop,step B = list(range(9)) print("This is List A:",A) print("This is List B:",B) 

Index the number 3 from A and the number 6 from B.

 print(A[2]) print(B[6]) 

Basic Slicing

Extended indexing syntax used for slicing is aList[start:stop:step]. The start argument and the step argument both default to none – the only required argument is stop. Did you notice this is similar to how range was used to define lists A and B? This is because the slice object represents the set of indices specified by range(start, stop, step). Python 3.4 documentation

As you can see, defining only stop returns one element. Since the start defaults to none, this translates into retrieving only one element.

It is important to note, the first element is index 0, NOT index 1. This is why we are using 2 lists for this exercise. List A’s elements are numbered according to the ordinal position (the first element is 1, the second element is 2, etc) while List B’s elements are the numbers that would be used to index them ([0] for the first element 0, etc).

With extended indexing syntax, we retrieve a range of values. For example, all values are retrieved with a colon.

 A[:] 

To retrieve a subset of elements, the start and stop positions need to be defined.

Given the pattern aList[start:stop], retrieve the first two elements from List A

It is easy to understand if we could relate slicing to range , which gives the indexes. We can categorize slicing into the following two categories:


1. No step or step > 0. For example, [i:j] or [i:j:k] (k>0)

Suppose the sequence is s=[1,2,3,4,5] .

  • if 0 and 0 , then [i:j:k] -> range(i,j,k)

For example, [0:3:2] -> range(0,3,2) -> 0, 2

  • if i>len(s) or j>len(s) , then i=len(s) or j=len(s)

For example, [0:100:2] -> range(0,len(s),2) -> range(0,5,2) -> 0, 2, 4

  • if i<0 or j<0 , then i=max(0,len(s)+i) or j=max(0,len(s)+j)

For example, [0:-3:2] -> range(0,len(s)-3,2) -> range(0,2,2) -> 0

For another example, [0:-1:2] -> range(0,len(s)-1,2) -> range(0,4,2) -> 0, 2

  • if i is not specified, then i=0

For example, [:4:2] -> range(0,4,2) -> range(0,4,2) -> 0, 2

  • if j is not specified, then j=len(s)

For example, [0::2] -> range(0,len(s),2) -> range(0,5,2) -> 0, 2, 4


2. Step < 0. For example, [i:j:k] (k<0)

Suppose the sequence is s=[1,2,3,4,5] .

  • if 0 and 0 , then [i:j:k] -> range(i,j,k)

For example, [5:0:-2] -> range(5,0,-2) -> 5, 3, 1

  • if i>len(s) or j>len(s) , then i=len(s)-1 or j=len(s)-1

For example, [100:0:-2] -> range(len(s)-1,0,-2) -> range(4,0,-2) -> 4, 2

  • if i<0 or j<0 , then i=max(-1,len(s)+i) or j=max(-1,len(s)+j)

For example, [-2:-10:-2] -> range(len(s)-2,-1,-2) -> range(3,-1,-2) -> 3, 1

  • if i is not specified, then i=len(s)-1

For example, [:0:-2] -> range(len(s)-1,0,-2) -> range(4,0,-2) -> 4, 2

  • if j is not specified, then j=-1

For example, [2::-2] -> range(2,-1,-2) -> 2, 0

For another example, [::-1] -> range(len(s)-1,-1,-1) -> range(4,-1,-1) -> 4, 3, 2, 1, 0


In summary

introduzca la descripción de la imagen aquí