Cómo funciona el corte en Python

Resuelto Simon asked hace 15 años • 38 respuestas

¿Cómo funciona la notación de corte de Python ? Es decir: cuando escribo código como a[x:y:z], etc., a[:]¿ a[::2]cómo puedo entender qué elementos terminan en el segmento?


Consulte ¿ Por qué el límite superior de corte y rango es exclusivo? para saber por qué xs[0:2] == [xs[0], xs[1]], no [..., xs[2]] .
Consulte Crear una nueva lista que contenga cada enésimo elemento de la lista original para xs[::N].
Consulte ¿Cómo funciona la asignación con sectores de lista? para aprender qué xs[0:2] = ["a", "b"]hace.

Simon avatar Feb 04 '09 05:02 Simon
Aceptado

La sintaxis es:

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 stepvalor, 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 el :stopvalor representa el primer valor que no está en el segmento seleccionado. Entonces, la diferencia entre stopy startes la cantidad de elementos seleccionados (si stepes 1, el valor predeterminado).

La otra característica es que starto stoppuede ser un número negativo , lo que significa que cuenta desde el final de la matriz en lugar del principio. Entonces:

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

De manera similar, steppuede 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 programador si hay menos elementos de los que solicita. Por ejemplo, si solicita a[:-2]y asolo contiene un elemento, obtendrá una lista vacía en lugar de un error. En ocasiones preferirías el error, por lo que tienes que ser consciente de que esto puede suceder.

Relación con el sliceobjeto

Un sliceobjeto puede representar una operación de corte, es decir:

a[start:stop:step]

es equivalente a:

a[slice(start, stop, step)]

Los objetos Slice también se comportan de forma ligeramente diferente dependiendo del número de argumentos, similar a , es decir, se admiten range()ambos slice(stop)y . slice(start, stop[, step])Para omitir la especificación de un argumento determinado, se podría utilizar None, de modo que, por ejemplo , a[start:]sea equivalente a a[slice(start, None)]o a[::-1]sea 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 slice()objetos simplifica la generación programática del corte.

Greg Hewgill avatar Feb 03 '2009 22:02 Greg Hewgill

El tutorial de Python habla de ello (desplácese un poco hacia abajo hasta llegar a la parte sobre corte).

El diagrama 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  -5  -4  -3  -2  -1

Una forma de recordar cómo funcionan los cortes es pensar que los índices apuntan entre 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 el índice n .

Hans Nowak avatar Feb 03 '2009 22:02 Hans Nowak

Enumerando las posibilidades que permite la gramática para la secuencia x:

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

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

Si stridees negativo, el orden cambia un poco ya que estamos en cuenta regresiva:

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

El corte extendido (con comas y elipses) se utiliza principalmente solo en estructuras de datos especiales (como NumPy); las secuencias básicas no las admiten.

>>> class slicee:
...     def __getitem__(self, item):
...         return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
ephemient avatar Feb 03 '2009 23:02 ephemient