Wie verwenden Sie die Ellipsen-Slicing-Syntax in Python?


Antworten:


102

Ellipsisoder ...ist kein verstecktes Merkmal, es ist nur eine Konstante. Es ist ganz anders als beispielsweise Javascript ES6, wo es Teil der Sprachsyntax ist. Keine eingebaute Klasse oder Python-Sprachkonstruktion nutzt sie.

Die Syntax dafür hängt also ganz davon ab, ob Sie oder jemand anderes Code geschrieben hat, um ihn zu verstehen.

Numpy verwendet es, wie in der Dokumentation angegeben . Einige Beispiele hier .

In Ihrer eigenen Klasse würden Sie es folgendermaßen verwenden:

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

Natürlich gibt es die Python-Dokumentation und die Sprachreferenz . Aber die sind nicht sehr hilfreich.


6
sieht ziemlich kaputt aus, da die "richtige" Art, alle Gegenstände zu sagen, >>> x [:] >>> x [:, 1: 2] ist
Ronny

30
@Ronny: Es ging darum, eine benutzerdefinierte Verwendung von Ellipsis zu demonstrieren.
Nosklo

7
Die Links scheinen defekt zu sein.
SwiftsNamesake

229

Die Ellipse wird in Numpy verwendet, um höherdimensionale Datenstrukturen zu schneiden.

Es wurde entwickelt , um meine an dieser Stelle einfügen , wie viele Vollscheiben ( :) , um die mehrdimensionale Scheibe auf alle Dimensionen zu erweitern .

Beispiel :

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

Jetzt haben Sie eine 4-dimensionale Matrix der Ordnung 2x2x2x2. Um alle ersten Elemente in der 4. Dimension auszuwählen, können Sie die Ellipsen-Notation verwenden

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

das ist äquivalent zu

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

In Ihren eigenen Implementierungen können Sie den oben genannten Vertrag ignorieren und für alles verwenden, was Sie für richtig halten.


Vielleicht irre ich mich, aber ist es nicht so, dass a[:,:,:,0]eine Kopie zurückgegeben wird und a[...,0]die "Ansicht" und nicht die Kopie zurückgegeben wird? Ich habe versucht, id()gegen beide Versionen und für ein 3-Dim-Array zu laufen : a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] Alle haben unterschiedliche IDs, während: a[..., 0], a[..., 1], a[..., 2] alle dieselben IDs haben.
Mohitsharma44

@ mohitsharma44 nicht auf meinem Computer;) id()gibt für beide den gleichen Wert zurück. Auch das Überprüfen mit __array_interface__['data']zeigt die gleiche Speicheradresse.
BoltzmannBrain

Ich finde, wir können verwenden, a[indexes, ...]während a sogar ein 1-dimensionales Array ist!
Acgtyrant

1
Ellipsen sind auch nützlich für nulldimensionale Datenstrukturen. Sie sind die einzige mir bekannte Möglichkeit, in skalare numpy.ndarrays zu schreiben, z. B.: My_scalar = np.asarray (3); my_scalar [...] = 5. Wenn Sie my_scalar [:] = 5 ausführen, wird zu Recht ein Fehler angezeigt, da es keine Dimension 0 gibt, über die: iteriert werden kann.
SuperElectric

1
@SuperElectric Sie können auch my_scalar.itemset (scalarvalue) verwenden. Natürlich ist my_scalar [...] = scalar_value kürzer, aber Sie haben im obigen Kommentar gesagt, dass dies der einzige Weg ist, den Sie kennen. Nur eine Alternative geben.
Kamathln

70

Dies ist eine weitere Verwendung für Ellipsis, die nichts mit Slices zu tun hat: Ich verwende sie häufig in der Thread-Kommunikation mit Warteschlangen als Markierung, die "Fertig" signalisiert. es ist da, es ist ein Objekt, es ist ein Singleton, und sein Name bedeutet "Mangel an", und es ist nicht das überstrapazierte None (das als Teil des normalen Datenflusses in eine Warteschlange gestellt werden könnte). YMMV.


14
Könnte es nicht klarer sein, irgendwo zu sagen: "Done = object ()" und das einfach zu benutzen?
Brandon Rhodes

12
Nicht unbedingt - Sie müssen tatsächlich irgendwo Done = object () sagen . Sentinel-Werte sind nicht unbedingt eine schlechte Sache - und die Verwendung von ansonsten fast nutzlosen Python-Singletons als Sentinels ist IMO nicht so schrecklich (Ellipsis und () sind diejenigen, die ich verwendet habe, bei denen None verwirrend wäre).
Rick Copeland

6
In Bezug auf Done = object () denke ich, dass die Verwendung von Ellipsis besser ist, insbesondere wenn Sie es für die Kommunikation mit Warteschlangen verwenden. Wenn Sie von der Intra-Thread- zur Intra-Prozess-Kommunikation wechseln, ist die ID (Fertig) im anderen Prozess nicht identisch, und es gibt nichts, was ein Objekt von einem anderen unterscheidet. Die ID von Ellipsis wird auch nicht dieselbe sein, aber zumindest der Typ wird dieselbe sein - dies ist der Punkt eines Singletons.
Tristan Reid

Die Frage lautet "Wie benutzt man Ellipsen?", Aber ich glaube, Sie haben das falsch verstanden. Es hat viele Interpretationen. Aber ich denke, das Richtige ist: "Wie wird Ellipse verwendet?" dh "Welche Schritte sollte ich unternehmen, um Ellipsis in meinem eigenen Code zu verwenden."
Lyndon White

6

Wie in anderen Antworten angegeben, kann es zum Erstellen von Slices verwendet werden. Nützlich, wenn Sie nicht viele vollständige Slices-Notationen ( :) schreiben möchten oder wenn Sie sich nicht sicher sind, wie dimensioniert das zu manipulierende Array ist.

Was ich für wichtig hielt, um hervorzuheben, und das bei den anderen Antworten fehlte, ist, dass es verwendet werden kann, auch wenn keine Dimensionen mehr gefüllt werden müssen.

Beispiel:

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

Dies führt zu einem Fehler:

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

Das wird funktionieren:

a[...,0,:]
array([0, 1])
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.