¿Cómo se usa la sintaxis de corte de puntos suspensivos en Python?


Respuestas:


102

Ellipsiso ...no es una característica oculta, es solo una constante. Es bastante diferente a, digamos, javascript ES6, donde forma parte de la sintaxis del lenguaje. Ninguna clase incorporada o construcción de lenguaje Python hace uso de ella.

Entonces, la sintaxis para ello depende completamente de que usted o alguien más tenga un código escrito para comprenderlo.

Numpy lo usa, como se indica en la documentación . Algunos ejemplos aquí .

En tu propia clase, lo usarías así:

>>> class TestEllipsis(object):
...     def __getitem__(self, item):
...         if item is Ellipsis:
...             return "Returning all items"
...         else:
...             return "return %r items" % item
... 
>>> x = TestEllipsis()
>>> print x[2]
return 2 items
>>> print x[...]
Returning all items

Por supuesto, está la documentación de Python y la referencia del lenguaje . Pero esos no son muy útiles.


66
parece bastante roto ya que la forma "adecuada" de decir todos los elementos es >>> x [:] >>> x [:, 1: 2]
— Ronny

30
@Ronny: El objetivo era demostrar un uso personalizado de puntos suspensivos.
— nosklo

77
Los enlaces parecen estar rotos.
— SwiftsNamesake

231

La elipsis se utiliza en numpy para cortar estructuras de datos de dimensiones superiores.

Está diseñado para significar en este punto, inserte tantos cortes completos ( :) para extender el corte multidimensional a todas las dimensiones .

Ejemplo :

>>> from numpy import arange
>>> a = arange(16).reshape(2,2,2,2)

Ahora, tiene una matriz de 4 dimensiones de orden 2x2x2x2. Para seleccionar todos los primeros elementos en la cuarta dimensión, puede usar la notación de puntos suspensivos

>>> a[..., 0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

que es equivalente a

>>> a[:,:,:,0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

En sus propias implementaciones, puede ignorar el contrato mencionado anteriormente y utilizarlo para lo que considere conveniente.


Tal vez estoy equivocado, pero ¿no es eso lo que a[:,:,:,0]devolverá una copia y a[...,0]devolverá la "vista" y no la copia? Intenté ejecutar id()contra ambas versiones y para una matriz de 3 dim: a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] todos tienen diferentes identificadores, mientras que: a[..., 0], a[..., 1], a[..., 2] todos tienen los mismos identificadores.
— mohitsharma44

@ mohitsharma44 no está en mi máquina;) id()devuelve el mismo valor para ambos. Verificando también __array_interface__['data']muestra la misma dirección de memoria.
— BoltzmannBrain

¡Creo que podemos usar a[indexes, ...]mientras que a es una matriz de 1 dimensión incluso!
— acgtyrant

1
Las elipses también son útiles para estructuras de datos de dimensión cero. Son la única forma que conozco para escribir en escalar numpy.ndarrays, por ejemplo: my_scalar = np.asarray (3); my_scalar [...] = 5. Si haces my_scalar [:] = 5, legítimamente obtendrás un error, porque no hay una dimensión 0 para: iterar.
— SuperElectric

1
@SuperElectric También puede usar my_scalar.itemset (scalarvalue). Por supuesto, my_scalar [...] = scalar_value es más corto, pero usted dijo en el comentario anterior, que es la única forma de saberlo. Solo dando una alternativa.
— kamathln

70

Este es otro uso para Ellipsis, que no tiene nada que ver con cortes: a menudo lo uso en comunicación intra-hilo con colas, como una marca que indica "Hecho"; está allí, es un objeto, es un singleton, y su nombre significa "falta de", y no es el None usado en exceso (que podría ponerse en una cola como parte del flujo de datos normal). YMMV.


14
¿No sería más claro decir: "Listo = objeto ()" en alguna parte y simplemente usar eso?
— Brandon Rhodes el

12
No necesariamente: requiere que digas Done = object () en alguna parte. Los valores de centinela no son necesariamente algo malo, y el uso de singletons de Python casi inútiles como centinelas no es tan horrible IMO (puntos suspensivos y () son los que he usado donde Ninguno sería confuso).
— Rick Copeland

66
Con respecto a Done = object (), creo que usar Ellipsis es mejor, especialmente si lo está usando para comunicarse con colas. Si pasa de la comunicación entre subprocesos a dentro del proceso, el id (Listo) no será el mismo en el otro proceso, y no hay nada que distinga un objeto de otro. El id de Ellipsis tampoco será el mismo, pero al menos el tipo será el mismo: este es el punto de un singleton.
— Tristan Reid el

La pregunta dice "¿Cómo usas los puntos suspensivos?", Pero creo que lo tomaste mal. Tiene muchas interpretaciones. Pero creo que lo correcto es: "¿Cómo se usa la elipsis?" es decir, "¿Qué pasos debo seguir para utilizar Elipsis en mi propio código?".
— Lyndon White

6

Como se indicó en otras respuestas, se puede usar para crear sectores. Útil cuando no desea escribir muchas anotaciones de cortes completos ( :), o cuando no está seguro de cuál es la dimensionalidad de la matriz que se está manipulando.

Lo que me pareció importante destacar, y que faltaba en las otras respuestas, es que se puede usar incluso cuando no hay más dimensiones que llenar.

Ejemplo:

>>> from numpy import arange
>>> a = arange(4).reshape(2,2)

Esto dará como resultado un error:

>>> a[:,0,:]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: too many indices for array

Esto funcionará:

a[...,0,:]
array([0, 1])
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.