Come si usa la sintassi di suddivisione dei puntini di sospensione in Python?


Risposte:


102

Ellipsiso ...non è una funzione nascosta, è solo una costante. È abbastanza diverso, per esempio, da javascript ES6 in cui fa parte della sintassi del linguaggio. Nessuna classe incorporata o struttura del linguaggio Python la utilizza.

Quindi la sintassi dipende interamente da te o da qualcun altro, che ha scritto codice per capirlo.

Numpy lo utilizza, come indicato nella documentazione . Alcuni esempi qui .

Nella tua classe, lo useresti in questo modo:

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

Naturalmente, c'è la documentazione di Python e il riferimento al linguaggio . Ma quelli non sono molto utili.


6
sembra abbastanza rotto dal modo "propper" di dire che tutti gli oggetti sono >>> x [:] >>> x [:, 1: 2]
Ronny

30
@Ronny: il punto era dimostrare un uso personalizzato dell'ellissi.
nosklo,

7
I collegamenti sembrano essere rotti.
SwiftsNamesake il

231

I puntini di sospensione vengono utilizzati in numpy per tagliare strutture di dati di dimensioni superiori.

È progettato per significare a questo punto, inserire tante sezioni intere ( :) per estendere la sezione multidimensionale a tutte le dimensioni .

Esempio :

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

Ora hai una matrice quadridimensionale di ordine 2x2x2x2. Per selezionare tutti i primi elementi nella 4a dimensione, è possibile utilizzare la notazione con i puntini di sospensione

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

che equivale a

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

Nelle tue implementazioni, sei libero di ignorare il contratto sopra menzionato e usarlo per quello che ritieni opportuno.


Forse mi sbaglio ma non è che a[:,:,:,0]restituirà una copia e a[...,0]restituirà la "vista" e non la copia? Ho provato a correre id()su entrambe le versioni e per un array a 3 dim: a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] tutti hanno ID diversi mentre: a[..., 0], a[..., 1], a[..., 2] tutti hanno gli stessi ID.
Mohitsharma44,

@ mohitsharma44 non sulla mia macchina;) id()restituisce lo stesso valore per entrambi. Anche il controllo con __array_interface__['data']mostra lo stesso indirizzo di memoria.
Boltzmann

Trovo che possiamo usare a[indexes, ...]mentre a è un array a 1 dimensione anche!
acgtyrant

1
Le ellissi sono utili anche per le strutture di dati a dimensione zero. Sono l'unico modo che conosco per scrivere in numpy.ndarrays scalari, ad esempio: my_scalar = np.asarray (3); my_scalar [...] = 5. Se fai my_scalar [:] = 5, otterrai giustamente un errore, perché non esiste una dimensione 0 per: iterate over.
SuperElectric,

1
@SuperElectric Puoi anche usare my_scalar.itemset (scalarvalue). Certo, my_scalar [...] = scalar_value è più breve, ma hai detto nel commento sopra, che è l'unico modo che conosci. Sto solo dando un'alternativa.
kamathln,

70

Questo è un altro uso di Ellipsis, che non ha nulla a che fare con le sezioni: lo uso spesso nella comunicazione intra-thread con le code, come un segno che segnala "Fatto"; è lì, è un oggetto, è un singleton e il suo nome significa "mancanza di", e non è il None abusato (che potrebbe essere inserito in una coda come parte del normale flusso di dati). YMMV.


14
Non potrebbe essere più chiaro dire semplicemente: "Fatto = oggetto ()" da qualche parte e usarlo?
Brandon Rhodes,

12
Non necessariamente - richiede effettivamente di dire Done = object () da qualche parte. I valori delle sentinelle non sono necessariamente una cosa negativa - e usare singleton Python altrimenti quasi inutili come sentinelle non è così orribile IMO (Ellissi e () sono quelli che ho usato dove Nessuno sarebbe confuso).
Rick Copeland,

6
Per quanto riguarda Done = object (), penso che usare Ellissi sia meglio, specialmente se lo stai usando per comunicare con le code. Se si passa dalla comunicazione intra-thread a quella intra-processo, id (Fatto) non sarà lo stesso nell'altro processo e non c'è nulla che distingua un oggetto da un altro. L'id di Ellipsis non sarà lo stesso, ma almeno il tipo sarà lo stesso: questo è il punto di un singleton.
Tristan Reid,

La domanda dice "Come si usano i puntini di sospensione" ma credo che tu l'abbia presa nel modo sbagliato. Ha molte interpretazioni. Ma penso che il corretto sia: "Come si usa l'ellissi?" vale a dire "Quali passi devo fare per utilizzare l'ellissi nel mio codice".
Lyndon White il

6

Come indicato in altre risposte, può essere utilizzato per creare sezioni. Utile quando non si desidera scrivere molte notazioni di sezioni complete ( :) o quando non si è sicuri su quale sia la dimensione dell'array manipolata.

Ciò che ho ritenuto importante evidenziare, e che mancava nelle altre risposte, è che può essere utilizzato anche quando non ci sono più dimensioni da riempire.

Esempio:

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

Ciò comporterà un errore:

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

Questo funzionerà:

a[...,0,:]
array([0, 1])
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.