Respuestas:
significa "nada para el primer argumento, nada para el segundo, y saltar por tres". Obtiene cada tercer elemento de la secuencia en rodajas. Rebanadas extendidas es lo que quieres. Nuevo en Python 2.3
range(10)[::3]salidas[0, 3, 6, 9]
::como [n ::]. Entonces, ¿qué quiere decir con n?
seq[::n]es una secuencia de cada nelemento en la secuencia completa.
Ejemplo:
>>> range(10)[::2]
[0, 2, 4, 6, 8]
La sintaxis es:
seq[start:end:step]
Entonces puedes hacer:
>>> range(100)[5:18:2]
[5, 7, 9, 11, 13, 15, 17]
s[i:j:k]es, según la documentación , "segmento de s de i a j con el paso k". Cuando iy jestán ausentes, se asume toda la secuencia y, por lo tanto, s[::k]significa "cada elemento k-ésimo".
Primero, inicialicemos una lista:
>>> s = range(20)
>>> s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Tomemos cada 3 rd elemento desde s:
>>> s[::3]
[0, 3, 6, 9, 12, 15, 18]
Tomemos cada 3 rd elemento desde s[2:]:
>>> s[2:]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> s[2::3]
[2, 5, 8, 11, 14, 17]
Tomemos cada 3 rd elemento desde s[5:12]:
>>> s[5:12]
[5, 6, 7, 8, 9, 10, 11]
>>> s[5:12:3]
[5, 8, 11]
Tomemos cada 3 rd elemento desde s[:10]:
>>> s[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> s[:10:3]
[0, 3, 6, 9]
Este ejemplo visual le mostrará cómo seleccionar elementos cuidadosamente en una matriz NumPy (matriz bidimensional) de una manera bastante entretenida (lo prometo). El paso 2 a continuación ilustra el uso de esos "dos puntos dobles" ::en cuestión.
(Precaución: este es un ejemplo específico de matriz NumPy con el objetivo de ilustrar el caso de uso de "dos puntos dobles" ::para saltar elementos en varios ejes. Este ejemplo no cubre las estructuras de datos nativas de Python List).
Digamos que tenemos una matriz NumPy que se ve así:
In [1]: import numpy as np
In [2]: X = np.arange(100).reshape(10,10)
In [3]: X
Out[3]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])
Digamos por alguna razón, su jefe quiere que seleccione los siguientes elementos:
"¿Pero cómo?" ... ¡Sigue leyendo! (Podemos hacer esto en un enfoque de 2 pasos)
Especifique el "índice de inicio" y el "índice de finalización" en las direcciones de fila y columna.
En codigo:
In [5]: X2 = X[2:9,3:8]
In [6]: X2
Out[6]:
array([[23, 24, 25, 26, 27],
[33, 34, 35, 36, 37],
[43, 44, 45, 46, 47],
[53, 54, 55, 56, 57],
[63, 64, 65, 66, 67],
[73, 74, 75, 76, 77],
[83, 84, 85, 86, 87]])
Observe ahora que acabamos de obtener nuestro subconjunto, con el uso de una simple técnica de indexación de inicio y fin. A continuación, cómo hacer ese "salto" ... (¡sigue leyendo!)
Ahora podemos especificar los "pasos de salto" en direcciones de fila y de columna (para seleccionar elementos de forma "de salto") de esta manera:
En el código (tenga en cuenta los dos puntos dobles):
In [7]: X3 = X2[::3, ::2]
In [8]: X3
Out[8]:
array([[23, 25, 27],
[53, 55, 57],
[83, 85, 87]])
¡Acabamos de seleccionar todos los elementos según sea necesario! :)
Ahora que conocemos el concepto, podemos combinar fácilmente el paso 1 y el paso 2 en un solo paso consolidado, para ser compactos:
In [9]: X4 = X[2:9,3:8][::3,::2]
In [10]: X4
Out[10]:
array([[23, 25, 27],
[53, 55, 57],
[83, 85, 87]])
¡Hecho!
X[2:9,3:8][::3,::2] = 0 (para reemplazar las entradas marcadas a 0). Si Xvuelve a escribir , verá que todas las entradas marcadas ahora están configuradas en 0.
Al cortar en Python, el tercer parámetro es el paso. Como otros mencionaron, vea Slices extendidos para una buena descripción.
Con este conocimiento, [::3]solo significa que no ha especificado ningún índice inicial o final para su segmento. Como ha especificado un paso, 3esto requerirá cada tercera entrada para somethingcomenzar en el primer índice. Por ejemplo:
>>> '123123123'[::3]
'111'
También puede usar esta notación en sus propias clases personalizadas para que haga lo que quiera
class C(object):
def __getitem__(self, k):
return k
# Single argument is passed directly.
assert C()[0] == 0
# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)
# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)
# If you omit any part of the slice notation, it becomes None.
assert C()[:] == slice(None, None, None)
assert C()[::] == slice(None, None, None)
assert C()[1::] == slice(1, None, None)
assert C()[:2:] == slice(None, 2, None)
assert C()[::3] == slice(None, None, 3)
# Tuple with a slice object:
assert C()[:, 1] == (slice(None, None, None), 1)
# Ellipsis class object.
assert C()[...] == Ellipsis
Entonces podemos abrir objetos de corte como:
s = slice(1, 2, 3)
assert s.start == 1
assert s.stop == 2
assert s.step == 3
Esto se usa notablemente en Numpy para cortar matrices multidimensionales en cualquier dirección.
Por supuesto, cualquier API sensata debería usarse ::3con la semántica habitual "cada 3".
Lo relacionado Ellipsisse trata más adelante en: ¿Qué hace el objeto de puntos suspensivos?
Python usa :: para separar el valor de Fin, el Inicio y el Paso.
[5::]. Entonces, ¿qué quiere decir con 5?