Pregunta

Necesito una buena explicación (las referencias son un plus) en Python rebanada de notación.

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

Se ve muy poderosa, pero yo no he conseguido mi cabeza alrededor de ella.

¿Fue útil?

Solución

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 existe la step valor, el cual puede ser usado con cualquier de los de arriba:

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

El punto clave a recordar es que el :stop valor representa el primer valor que es no en el sector seleccionado.Así, la diferencia entre stop y start es el número de elementos seleccionados (si step es 1, el valor predeterminado).

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

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, 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 bueno para el programador si hay menos elementos que usted pida.Por ejemplo, si usted pide a[:-2] y a contiene un solo elemento, se obtiene una lista vacía en lugar de un error.A veces se prefiere el error, así que tienes que ser consciente de que esto puede suceder.

Relación con slice() objeto

La segmentación del operador [] realmente se utiliza en el código de arriba con un slice() objeto con la : la notación (que sólo es válida dentro de la []), es decir:

a[start:stop:step]

es equivalente a:

a[slice(start, stop, step)]

Objetos de división también se comporta de forma ligeramente diferente, dependiendo del número de argumentos, de manera similar a range(), es decir,ambos slice(stop) y slice(start, stop[, step]) son compatibles.Para omitir la especificación de un argumento dado, uno 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)].

Mientras que el :basado en la notación es muy útil para la simple corte, el uso explícito de slice() los objetos simplifica la programación de la generación de rebanar.

Otros consejos

Guía de aprendizaje de habla de él (baje un poco hasta que llegue a la parte de corte en rodajas).

El diagrama de arte ASCII es útil también para recordar cómo funcionan las rebanadas:

 +---+---+---+---+---+---+
 | 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 rebanadas de trabajo es pensar en los índices apuntando como entre caracteres, con el borde izquierdo del primer carácter número 0. Entonces el borde derecho del último carácter de una cadena de n personajes tiene índice n .

Enumeración de 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, entonces el punto final será un poco menor que high-1.

Si stride es negativo, el pedido se cambia un poco ya que estamos contando:

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

slicing extendida (con comas y elipses) se utilizan en su mayoría sólo por las estructuras de datos especiales (como NumPy); las secuencias básicas no son compatibles con ellos.

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

Las respuestas anteriores no discuten la asignación rebanada. Para comprender la asignación rebanada, es útil añadir 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, por una rebanada de cero a n, piensa:. "El cero es el principio, empezar por el principio y tomar n elementos de 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, "por cualquier rebanada, sustituir el principio por cero, aplicar la heurística anterior para llegar al final de la lista, y luego contar el primer número de copia de seguridad a picar artículos 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 asignación rebanada es que desde fragmentación retornos una lista, misiones rebanada 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 "<stdin>", line 1, in <module>
TypeError: can only assign an iterable

La segunda regla de asignación de corte, que también se puede ver arriba, es que cualquier parte de la lista es devuelto por la indexación de corte, que es la misma porción que se cambia por la asignación rebanada:

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

La tercera regla de asignación rebanada es decir, la lista asignada (iterable) no tiene que tener la misma longitud; la rodaja indexados es simplemente rodajas y reemplazado en masa por lo que se está asignado:

>>> 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 complicada para acostumbrarse a es la asignación de vaciar rodajas. El uso de heurística 1 y 2 es fácil de conseguir su cabeza alrededor de indexación una rodaja de vacío:

>>> 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 a continuación, una vez que se ha visto que, misiones de división para el corte vacío tiene sentido también:

>>> 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 rodaja (4), los elementos insertados siempre se apilan hasta en contra de la 'o', incluso cuando estamos asignando a la división vacía. Así la posición de la asignación rebanada vacío es la extensión lógica de las posiciones para las asignaciones de rebanada no vacíos.

Copia de seguridad un poco, lo que sucede cuando seguir adelante con nuestra procesión de contar hasta el corte de comenzar?

>>> 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 corte en rodajas, una vez que haya terminado, ya está hecho; no se inicia cortando hacia atrás. En Python no obtiene avances negativos a menos que se pide explícitamente que para ellos mediante el uso de un número negativo.

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

Hay algunas consecuencias extrañas a la regla "una vez que haya terminado, ya está hecho":

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

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

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

Esto puede ser útil a veces, pero también puede conducir a un comportamiento un tanto extraña:

>>> 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 la aplicación, que podría o no podría ... ... ser lo que era el esperar allí!


A continuación se muestra el texto de mi respuesta original. Ha sido útil para muchas personas, por lo que no quieren eliminarlo.

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

Explicar Python rebanada de notación

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

sliceable[start:stop:step]

Python la segmentación es una de cómputo de manera rápida metódicamente acceder a partes de sus datos.En mi opinión, para ser incluso un intermedio programador Python, es un aspecto de la lengua que es necesario estar familiarizado con.

Definiciones Importantes

Para empezar, vamos a definir algunos términos:

inicio: el inicio índice del sector, se incluirá el elemento en este índice a menos que sea el mismo que parada, el valor predeterminado es 0, es decir,el primer índice.Si es negativo, significa empezar n elementos de la final.

stop: el índice de finalización de la rebanada, no no incluir el elemento en este índice, el valor por defecto de la longitud de la secuencia que se rodajas, que es, hasta e incluyendo la final.

paso: la cantidad por la cual el índice aumenta, el valor por defecto de 1.Si es negativa, estás segmentando más de la iterable a la inversa.

Cómo Indexación De Obras

Usted puede hacer cualquiera de estos números positivos o negativos.El significado de los números positivos es sencillo, pero para los números negativos, como los índices en Python, que cuente hacia atrás desde el final de la inicio y parada, y para el paso, usted simplemente disminuir su índice.Este ejemplo es a partir de la documentación del tutorial, pero he modificado ligeramente para indicar que el elemento en una secuencia de cada una de las referencias de índice:

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

Cómo Rebanar Obras

El uso de la notación de segmentos con una secuencia que admite, debe incluir al menos uno de los dos puntos en los corchetes que seguir la secuencia (que en realidad implementar el __getitem__ método de la secuencia, de acuerdo con el modelo de datos de Python.)

La notación de segmentos trabaja como esto:

sequence[start:stop:step]

Y recordar que no son los valores predeterminados para inicio, parada, y paso, por lo que para acceder a los valores predeterminados, simplemente dejar fuera de la discusión.

La notación de segmentos para obtener los últimos nueve elementos de una lista (o cualquier otra secuencia que admite, como una cadena) tendría este aspecto:

my_list[-9:]

Cuando veo esto, acabo de leer la parte en los soportes como "9 desde el final, hasta el final." (En realidad, me abreviar mentalmente como "-9, en")

Explicación:

La notación completa es

my_list[-9:None:None]

y sustituir los valores por defecto (cuando en realidad step es negativo, stop's valor predeterminado es -len(my_list) - 1, por lo que None para detener, en realidad, significa que va a lo que paso final la lleva):

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

El colon, :, es lo que le dice a Python que usted está dando un sector y no un índice normal.Es por eso que el idiomáticas manera de hacer una copia superficial de las listas en Python 2 es

list_copy = sequence[:]

Y la limpieza es con:

del my_list[:]

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

Cuando step es negativo, los valores predeterminados para start y stop cambio

Por defecto, cuando la step argumento está vacío (o None), se le asigna a +1.

Pero puede pasar en un entero negativo, y la lista (o la mayoría de los demás estándar slicables) va a ser cortado desde el final hasta el principio.

Por lo tanto una negativa rebanada va a cambiar los valores predeterminados para start y stop!

Confirmando esta en la fuente

Me gustaría animar a los usuarios a leer la fuente así como de la documentación.El código fuente para objetos de división y esta lógica se encuentra aquí.Primero debemos determinar si step es negativo:

 step_is_negative = step_sign < 0;

Si es así, el límite inferior es -1 lo que significa que cortar todo el camino hasta e incluyendo el principio, y el límite superior es la longitud de menos 1, es decir, que empezar por el final.(Tenga en cuenta que la semántica de este -1 es diferentes a partir de una -1 que los usuarios puedan pasar los índices en Python que indica 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, step es positivo, y el límite inferior será cero y el límite superior (que vamos a ir hasta, pero no incluyendo) la longitud de los gajos de la lista.

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

Entonces, podemos necesitar para aplicar los valores predeterminados para start y stop - el valor predeterminado, a continuación, para start se calcula como el límite superior cuando 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);
}

Dar a su rodajas de un nombre descriptivo!

Usted puede encontrar que es útil para separar la formación de la división de pasar a la list.__getitem__ (método deeso es lo que los corchetes ¿).Incluso si no eres nuevo en esto, se mantiene el código más legible para que otros que pueden tener para leer el código puede comprender más fácilmente lo que estás haciendo.

Sin embargo, usted no puede simplemente asignar algunos enteros separados por dos puntos a una variable.Usted necesidad de utilizar el objeto de división:

last_nine_slice = slice(-9, None)

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

Usted puede pasar el objeto de división a la secuencia:

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

Es interesante que los rangos también tomar los trozos:

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

Consideraciones Acerca De La Memoria:

Desde las rodajas de las listas de Python crear nuevos objetos en la memoria, otra función importante a tener en cuenta es itertools.islice.Normalmente, usted querrá para iterar sobre un sector, no sólo han creado de forma estática en la memoria. islice es perfecto para ello.Una advertencia, no admite argumentos negativos para start, stop, o step, así que si ese es un problema que usted puede necesitar para calcular los índices o revertir la 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 la lista de rodajas de hacer una copia es una característica de las listas de sí mismos.Si estás segmentando avanzada de objetos como un Pandas DataFrame, puede devolver un punto de vista sobre el original y no una copia.

Y un par de cosas que no estaban inmediatamente obvio para mí cuando vi por primera vez la sintaxis de rebanado:

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

Una forma sencilla de secuencias de revertir!

Y si usted quiere, por alguna razón, cada segundo elemento en el orden inverso:

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

asignación de índice de comprensión 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 usted dice [a: b: c], está diciendo en función de la señal de c (hacia delante o hacia atrás), comenzar en un extremo y en b (excluyendo elemento en el índice BTH). Use la regla de indexación anterior y recordar sólo 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
             a    s    t   r    i   n   g
    -9  -8  -7   -6   -5  -4   -3  -2  -1

Si su elección de a, b, yc permite la superposición con el intervalo anterior a medida que atraviesan el uso de normas para a, b, c por encima de que o bien obtener una lista con los elementos (tocados durante el recorrido) o se obtendrá un vacío lista.

Una última cosa: si a y b son iguales, entonces también se obtiene 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]

Encuentra este gran mesa 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 di 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 son opcionales:

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

A continuación, la indexación negativa simplemente se tiene que añadir la longitud de la cadena a los índices negativos de entenderlo.

Esto funciona para mí de todos modos ...

Me resulta más fácil recordar cómo funciona, y entonces puedo averiguar específicas de inicio/parar/paso combinación.

Es útil comprender 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

Comenzará a partir de start, el incremento por step, no llegan a stop.Muy simple.

La cosa a recordar sobre el avance negativo es que stop es siempre la excluido final, si es mayor o menor.Si desea misma división en el orden contrario, es mucho más limpio para hacer la inversión por separado:por ejemplo, 'abcde'[1:-2][::-1] rebanadas de descuento en un char desde la izquierda, dos a la derecha, y a continuación se invierte.(Ver también reversed().)

La secuencia de la segmentación es la misma, excepto en el primero se normaliza índices negativos, y que nunca puede ir fuera de la secuencia:

TODO:El código de abajo había un error con "nunca fuera de la secuencia" cuando el abs(paso)>1;Yo creo He parcheado 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 te preocupes por el is None detalles - sólo recuerda que la omisión de start y/o stop siempre hace lo correcto para darle toda la secuencia.

La normalización de índices negativos en primer lugar permite iniciar y/o detener a contar desde el final de forma independiente: 'abcde'[1:-2] == 'abcde'[1:3] == 'bc' a pesar de range(1,-2) == [].La normalización es a veces la idea de "modulo de la longitud", pero la nota se añade la longitud de sólo una vez:por ejemplo, 'abcde'[-53:42] es sólo el conjunto de la cadena.

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 ayude a que el modelo de la lista en Python.

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

Yo uso el método de "puntos entre los elementos de un índice" de pensar acerca de mí mismo, sino una manera de describir lo que a veces ayuda a otros a obtener es la siguiente:

mylist[X:Y]

X es el índice del primer elemento que desee.
Y es el índice del primer elemento que No que desee.

Python rebanar la notación:

a[start:end:step]
  • Para start y end, los valores negativos se interpretan como relativa a la final de la secuencia.
  • Positiva de los índices de end indicar la posición después de el último elemento a incluir.
  • Los valores en blanco están en mora de la siguiente manera: [+0:-0:1].
  • El uso de un avance negativo se invierte la interpretación de start y end

La notación se extiende a (numpy) matrices y matrices multidimensionales.Por ejemplo, para cortar todas las columnas que usted puede utilizar:

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

Rebanadas de mantener las referencias, no las copias, de los elementos de la matriz.Si desea hacer una copia separada de una matriz, puede utilizar deepcopy().

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

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

Esta es la forma en que enseño rebanadas a los novatos:

Comprensión diferencia entre la indexación y rebanar:

Wiki Python tiene esta imagen sorprendente que distingue claramente la indexación y rebanar.

introducir descripción de la imagen aquí

Es una lista con 6 elementos en el mismo. Para entender mejor cortar, tenga en cuenta que la lista como un conjunto de seis cajas se colocan juntos. Cada caja tiene un alfabeto en ella.

La indexación es como tratar con el contenido de la caja. Puede comprobar el contenido de cualquier caja. Pero no se puede comprobar el contenido de varias cajas a la vez. Incluso puede reemplazar el contenido de la caja. Pero no se 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)
<ipython-input-129-c7eb16585371> in <module>()
----> 1 alpha[0,1]

TypeError: list indices must be integers, not tuple

rebanar es como tratar con cajas de sí mismo. Puede primera caja de la camioneta y colocarlo en otra mesa. Para capturar la caja todo lo que necesita saber es la posición de inicio y de finalización de la caja.

Puede incluso recogida primera o última 3 cajas 2 cajas o todas las casillas de entre 1 y 4. Por lo tanto, usted puede escoger cualquier conjunto de cajas si usted sabe que comienza y termina. Este posiciones se denominan posiciones de inicio y parada.

Lo interesante es que se puede reemplazar varios cuadros a la vez. También puede colocar varias cajas donde quiera que te gusta.

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']

cortafiambres con Paso:

Hasta ahora las cajas que han recogido de forma continua. Sin embargo, algunas veces se necesitan para recoger discretamente. Por ejemplo, usted puede recoger cada segundo cuadro. Puede incluso pastilla cada tercer cuadro del final. Este valor se denomina tamaño de paso. Esto representa la brecha entre sus recolecciones sucesivas. El tamaño del paso debe ser positivo si usted va a recoger las cajas 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 se da cuenta de Python parámetros que faltan:

Durante el corte si dejar de lado cualquier parámetro, Python trata de resolverlo de forma automática.

Si marca el código fuente de CPython, encontrará una función llamada PySlice_GetIndicesEx el que se da cuenta de índices para un sector para los parámetros dados. Aquí está el código equivalente lógico en Python.

Esta función toma un objeto de Python y parámetros opcionales para cortar y empezar rendimientos, detener el paso y longitud rebanada 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 rebanada, puede pasar algunos parámetros y comprobar cómo inteligentemente que calcula los parámetros que faltan.

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: Este post está escrito originalmente en mi blog http://www.avilpage.com/2015/03/a-slice-of-python-intelligence-behind.html

Esto es sólo para algo más de info...Considere la lista de abajo

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

Como regla general, la escritura de código con una gran cantidad de valores de índice codificados conduce a una legibilidad y el desorden de mantenimiento. Por ejemplo, si usted se vuelve al código de un año más tarde, se le lo mira y se pregunta lo que estabas pensando cuando lo escribió. La solución mostrada es simplemente una manera de indicar más claramente lo que su código está haciendo realidad. En general, la rebanada incorporado () crea un objeto de división que puede ser utilizado en cualquier lugar una rebanada esta permitido. 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 rebanada s, se puede obtener más información sobre ella mirando su s.start, atributos s.stop y s.step, respectivamente. Por ejemplo:

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

1. Slice Notación

Para hacerlo simple, recuerde rebanada tiene una sola forma:

s[start:end:step]

y aquí es cómo funciona:

  • s: un objeto que puede ser cortado en lonchas
  • start: primer índice para iniciar la iteración
  • end: último índice, NOTA de que step índice no será incluido en el corte dado lugar
  • 0: cada elemento de toma len(s) índice

Otra cosa importación: todos 1, start>=end, step>0 se puede omitir Y si se omiten, se utilizará el valor por defecto: [], s[::-1] , s[0] consecuencia.

Así variaciones posibles 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[:]

NOTA:. Si <=> (teniendo en cuenta sólo cuando <=>), pitón volverá una rebanada vacío <=>

2. Trampas

La parte superior se explican las características fundamentales sobre cómo funciona la rebanada, que funcionará en la mayoría de las ocasiones. Sin embargo no puede haber trampas usted debe mirar hacia fuera, y esta parte los explica.

índices negativos

La primera cosa que confunde a los estudiantes pitón es que índice puede ser negativo! No se asuste:. índice negativo significa contar desde atrás

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]

paso Negativo

Hacer las cosas más confuso es que <=> puede ser negativo también!

paso negativa significa iterar la matriz hacia atrás:. De un extremo a empezar, con el índice final incluida, y empezar índice excluidos de resultado

NOTA : cuando paso es negativo, el valor por defecto para <=> a <=> (mientras <=> no es igual a <=>, porque <=> contiene <=>) . Por ejemplo:

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

Fuera de error de rango?

se sorprenda: rebanada no plantea IndexError cuando el índice está fuera del rango

Si el índice está fuera de rango, pitón intentará su mejor conjunto del índice de <=> o <=> de acuerdo a la situación. 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. Ejemplos

Vamos a terminar esta respuesta con ejemplos explica todo lo que hemos discutido:

# 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)
<ipython-input-15-79ffc22473a3> in <module>()
----> 1 s[11]

IndexError: list index out of range

Las respuestas anteriores no discuten múltiples dimensional rebanar matriz que es posible utilizando el famoso paquete de NumPy:

rebanar también se puede aplicar a una matriz multi-dimensionales.

# 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]])

El ":2" antes de coma opera en la primera dimensión y el "0:3:2" después de la coma opera en la segunda dimensión.

#!/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)

Puede ejecutar este guión y experimentar con él, a continuación hay algunas muestras que obtuve de la secuencia de comandos.

  +---+---+---+---+---+---+---+---+---+
  | 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]

Cuando se utiliza un paso negativo, se dio cuenta de que la respuesta se desplaza a la derecha en 1.

Mi cerebro parece dispuesto a aceptar que contiene el lst[start:end] start - el artículo del th. Incluso podría decir que es una 'suposición natural'.

Sin embargo, de vez en cuando a dudas se arrastra en mi cerebro y pide garantías de que no contiene el end -. Ésimo elemento

En estos momentos que dependen de este teorema simple:

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

Esta propiedad bastante me dice que lst[end:] no contiene el n -. º elemento porque está en True

Tenga en cuenta que este teorema es cierto para cualquier <=> en absoluto. Por ejemplo, se puede comprobar que

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

retornos <=>.

En Python, la forma más básica de corte es la siguiente:

l[start:end]

donde l es algo de la colección, start es un integrador índice y end es un exclusivo índice.

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]

Cuando rebanar desde el inicio, se puede omitir el índice de cero, y cuando rebanar hasta el final, puede omitir el índice final, ya que es redundante, por lo que no se verbose:

In [5]: l[:3] == l[0:3]
Out[5]: True

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

Los números enteros negativos son útiles a la hora de hacer desplazamientos en relación a la final de una colección:

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]

Es posible proporcionar índices que están fuera de los límites cuando rebanar, tales como:

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]

Tenga en cuenta que el resultado de dividir una colección es un conjunto de la nueva colección.Además, cuando se utiliza la notación de segmentos en las tareas, la duración de la rebanada de la asignación no necesita ser el mismo.Los valores antes y después de la porción asignada se mantendrá, y la recogida de la disminución o el aumento de contener a los nuevos valores:

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]

Si se omite el inicio y el final del índice, se hará una copia de la colección:

In [14]: l_copy = l[:]

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

Si el inicio y el final de los índices se omiten cuando se realiza una operación de asignación, todo el contenido de la colección, será reemplazada con una copia de lo que se hace referencia:

In [20]: l[:] = list('hello...')

In [21]: l
Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.']

Además básicas de corte, también es posible aplicar la siguiente notación:

l[start:end:step]

donde l es una colección, start es un integrador de índice, end es un exclusivo índice, y step es un paso que puede ser utilizado para tomar todas las n elemento en 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]

El uso de step proporciona un útil truco para invertir en una colección en Python:

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

También es posible utilizar los números enteros negativos para step como el siguiente ejemplo:

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

Sin embargo, el uso de un valor negativo para step podría llegar a ser muy confuso.Por otra parte, con el fin de ser Python, debe evitar el uso de start, end, y step en un solo sector.En caso de que esto sea necesario, considerar la posibilidad de hacerlo en dos trabajos (uno para cortar, y el otro a la zancada).

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]

La mayoría de las respuestas anteriores borra sobre la notación de la rebanada. sintaxis extendida de indexación utilizado para cortar en rodajas es aList[start:stop:step] ejemplos básicos son

 introducir descripción de la imagen aquí :

Ejemplos más de cortado: 15 rebanadas extendidas

El abajo es el ejemplo de índice de una cadena

 +---+---+---+---+---+
 | H | e | l | p | A |
 +---+---+---+---+---+
 0   1   2   3   4   5
-5  -4  -3  -2  -1

str="Name string"

ejemplo rebanar: [Inicio: Fin: paso]

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

A continuación se muestra el ejemplo de uso

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

Quiero añadir un ejemplo de Hello world que explica los conceptos básicos de los sectores para los principiantes.Me ayudó mucho.

Vamos a tener una lista con seis valores ['P', 'Y', 'T', 'H', 'O', 'N']:

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

Ahora los más simples rodajas de esa lista son sus sublistas.La notación es [<index>:<index>] y la clave es leer algo como esto:

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

Ahora bien, si usted hace una rebanada [2:5] de la lista anterior, esto va a suceder:

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

Se realizó un corte antes de el elemento con índice de 2 y otro corte antes de el elemento con índice de 5.Así, el resultado será una división entre los dos cortes, una lista de ['T', 'H', 'O'].

En mi opinión, va a entender y memorizar mejor la notación de cadena de rebanar Python si se mira la siguiente manera (leyendo).

Vamos a trabajar con la siguiente cadena ...

azString = "abcdefghijklmnopqrstuvwxyz"

Para aquellos que no lo saben, usted puede crear cualquier subcadena de azString usando la notación azString[x:y]

procedentes de otros lenguajes de programación, que es cuando el sentido común es comprometida. ¿Cuáles son xey?

tuviera que sentarse y ejecutar varios escenarios en mi búsqueda de una técnica de memorización que le ayudará a recordar lo que X e Y son y me ayude a rebanaré cuerdas correctamente en el primer intento.

Mi conclusión es que X e Y debe ser visto como los índices de límites que rodean a las cuerdas que queremos adicional. Así que hay que ver la expresión como azString[index1, index2] o incluso más clara a medida azString[index_of_first_character, index_after_the_last_character].

Aquí hay un ejemplo de la visualización que ...

Letters   a b c d e f g h i j ...
         ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 
Indexes  0 1 2 3 4 5 6 7 8 9 ... 
             |           |
cdefgh    index1       index2

Así que todo lo que tiene que hacer para establecer si index1 y index2 a los valores que rodearán la subcadena deseada. Por ejemplo, para obtener la subcadena "CDEFGH", puede utilizar azString[2:8] porque el índice en el lado izquierdo de la "c" es 2 y el otro en el tamaño adecuado de la "h" es 8.

Recuerde que estamos estableciendo los límites. Y esos límites son las posiciones donde se puede colocar algunos soportes que se envuelven alrededor de la subcadena como este ...

a b [ c d e f g h ] i j

Ese truco funciona todo el tiempo y es fácil de memorizar.

Si se siente índices negativos en el corte es confuso, aquí es muy fácil manera de pensar en ello: basta con sustituir índice negativo con len - index. Así, por ejemplo, sustituir -3 con len(list) - 3.

La mejor manera de ilustrar lo que rebanar no solo internamente se muestran en el código que implementa esta operación:

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)]

La técnica básica de rebanado es definir el punto de partida, el punto de parada, y el tamaño de paso - también conocido como zancada

.

En primer lugar, vamos a crear una lista de valores a utilizar en nuestra corte.

Crear dos listas para rebanar, la primera es una lista numérica del 1 al 9 (Lista A). El segundo es también una lista numérica, de 0 a 9 (Lista 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)

Índice el número 3 de A y el número 6 de B.

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

Básico de fragmentación

la sintaxis de indexación

Extended utilizado para cortar en rodajas es aList [Inicio: parada: paso]. El argumento de inicio y el argumento de paso, tanto por defecto a ninguno - el único argumento necesario es detener. ¿Se dio cuenta que esto es similar a cómo se utilizó rango para definir las listas A y B? Esto es porque el objeto de división representa el conjunto de los índices especificados por rango (iniciar, detener, paso). Python 3.4 documentación

Como se puede ver, la definición única parada vuelve un elemento. Dado que los valores por defecto de puesta a ninguno, esto se traduce en la recuperación de un solo elemento.

Es importante tener en cuenta, el primer elemento es el índice 0, NO Índice 1. Por esta razón, estamos utilizando 2 listas para este ejercicio. elementos de la Lista A se numeran de acuerdo con la posición ordinal (el primer elemento es 1, el segundo elemento es 2, etc.) mientras que los elementos de la Lista B son los números que serían utilizadas para indexar ellos ([0] para el primer elemento 0, etc ).

Con la indexación de sintaxis extendida, recuperamos un rango de valores. Por ejemplo, todos los valores se recuperan con un colon.

A[:]

Para recuperar un subconjunto de elementos, el inicio y parada posiciones necesitan ser definidos.

Dado el patrón aList [Inicio: stop], recuperar los dos primeros elementos de la Lista A

Es fácil de entender si nos podría relacionarse rebanar a range, que da a los índices.Podemos clasificar rebanar en las dos categorías siguientes:


1.No paso a paso o paso > 0.Por ejemplo, [i:j] o [i:j:k] (k>0)

Supongamos que la secuencia es s=[1,2,3,4,5].

  • si 0<i<len(s) y 0<j<len(s), a continuación, [i:j:k] -> range(i,j,k)

Por ejemplo, [0:3:2] -> range(0,3,2) -> 0, 2

  • si i>len(s) o j>len(s), a continuación, i=len(s) o j=len(s)

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

  • si i<0 o j<0, a continuación, i=max(0,len(s)+i) o j=max(0,len(s)+j)

Por ejemplo, [0:-3:2] -> range(0,len(s)-3,2) -> range(0,2,2) -> 0

Para otro ejemplo, [0:-1:2] -> range(0,len(s)-1,2) -> range(0,4,2) -> 0, 2

  • si i no es especificado, entonces i=0

Por ejemplo, [:4:2] -> range(0,4,2) -> range(0,4,2) -> 0, 2

  • si j no es especificado, entonces j=len(s)

Por ejemplo, [0::2] -> range(0,len(s),2) -> range(0,5,2) -> 0, 2, 4


2.Paso < 0.Por ejemplo, [i:j:k] (k<0)

Supongamos que la secuencia es s=[1,2,3,4,5].

  • si 0<i<len(s) y 0<j<len(s), a continuación, [i:j:k] -> range(i,j,k)

Por ejemplo, [5:0:-2] -> range(5,0,-2) -> 5, 3, 1

  • si i>len(s) o j>len(s), a continuación, i=len(s)-1 o j=len(s)-1

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

  • si i<0 o j<0, a continuación, i=max(-1,len(s)+i) o j=max(-1,len(s)+j)

Por ejemplo, [-2:-10:-2] -> range(len(s)-2,-1,-2) -> range(3,-1,-2) -> 3, 1

  • si i no es especificado, entonces i=len(s)-1

Por ejemplo, [:0:-2] -> range(len(s)-1,0,-2) -> range(4,0,-2) -> 4, 2

  • si j no es especificado, entonces j=-1

Por ejemplo, [2::-2] -> range(2,-1,-2) -> 2, 0

Para otro ejemplo, [::-1] -> range(len(s)-1,-1,-1) -> range(4,-1,-1) -> 4, 3, 2, 1, 0


En resumen

enter image description here

No creo que la Guía de aprendizaje de diagrama ( citado en varias otras respuestas) es buena ya que esta sugerencia trabaja para paso positivo, pero no para un paso negativo.

Este es el diagrama:

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

A partir del diagrama, espero a[-4,-6,-1] ser yP pero es ty.

>>> a = "Python"
>>> a[2:4:1] # as expected
'th'
>>> a[-4:-6:-1] # off by 1
'ty'

Lo que siempre funciona es pensar en caracteres o ranuras y utilizar la indexación como un intervalo semiabierto -. Derecha abierta si paso positivo, de izquierda abierta si paso negativo

De esta manera, se me ocurre a[-4:-6:-1] como a(-6,-4] en la terminología intervalo.

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

 +---+---+---+---+---+---+---+---+---+---+---+---+
 | P | y | t | h | o | n | P | y | t | h | o | n |
 +---+---+---+---+---+---+---+---+---+---+---+---+
  -6  -5  -4  -3  -2  -1   0   1   2   3   4   5  
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top