Jak używać składni krojenia wielokropka w Pythonie?

Odpowiedzi:

102

Ellipsislub ...nie jest funkcją ukrytą, jest po prostu stałą. Jest zupełnie inny niż, powiedzmy, javascript ES6, gdzie jest częścią składni języka. Żadna wbudowana klasa ani konstrukcja języka Python go nie wykorzystują.

Tak więc składnia zależy wyłącznie od Ciebie lub kogoś innego, kto napisał kod, aby to zrozumieć.

Numpy go używa, jak stwierdzono w dokumentacji . Kilka przykładów tutaj .

W swojej własnej klasie używałbyś tego w następujący sposób:

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

Oczywiście istnieje dokumentacja Pythona i odniesienie do języka . Ale to nie jest zbyt pomocne.

nosklo
źródło
6
wygląda na całkiem zepsutą, ponieważ „właściwy” sposób na określenie wszystkich pozycji to >>> x [:] >>> x [:, 1: 2]
Ronny
30
@Ronny: Chodziło o zademonstrowanie niestandardowego wykorzystania wielokropka.
nosklo
7
Linki wydają się być uszkodzone.
SwiftsNamesake
231

Wielokropek jest używany w numpy do wycinania bardziej wymiarowych struktur danych.

Ma to oznaczać w tym momencie wstawienie jak największej liczby pełnych plasterków ( :), aby rozszerzyć wielowymiarowy plaster na wszystkie wymiary .

Przykład :

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

Teraz masz 4-wymiarową macierz rzędu 2x2x2x2. Aby wybrać wszystkie pierwsze elementy w czwartym wymiarze, możesz użyć notacji wielokropka

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

co jest równoważne

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

We własnych implementacjach możesz zignorować powyższą umowę i używać jej do wszystkiego, co uznasz za stosowne.

Torsten Marek
źródło
Może się mylę, ale czy to nie a[:,:,:,0]zwróci kopię i a[...,0]zwróci „widok”, a nie kopię? Próbowałem uruchomić id()z obiema wersjami i dla tablicy 3-dim: a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] wszystkie mają różne identyfikatory, podczas gdy: a[..., 0], a[..., 1], a[..., 2] wszystkie mają takie same identyfikatory.
mohitsharma44
@ mohitsharma44 nie na moim komputerze;) id()zwraca tę samą wartość dla obu. Sprawdzanie również __array_interface__['data']pokazuje ten sam adres pamięci.
BoltzmannBrain
Uważam, że możemy użyć, a[indexes, ...]gdy a jest tablicą 1-wymiarową!
akgatyrant
1
Elipsy są również przydatne w przypadku zerowymiarowych struktur danych. Są to jedyne znane mi sposoby zapisywania w skalarnych numpy.ndarrays, np .: my_scalar = np.asarray (3); my_scalar [...] = 5. Jeśli zrobisz my_scalar [:] = 5, słusznie otrzymasz błąd, ponieważ nie ma wymiaru 0 dla: do iteracji.
SuperElectric
1
@SuperElectric Możesz także użyć my_scalar.itemset (scalarvalue). Oczywiście my_scalar [...] = scalar_value jest krótsza, ale w powyższym komentarzu powiedziałeś, że to jedyny sposób, jaki znasz. Po prostu dając alternatywę.
kamathln
70

Jest to kolejne zastosowanie wielokropka, które nie ma nic wspólnego z odcinkami: często używam go w komunikacji wewnątrz wątku z kolejkami, jako znacznika sygnalizującego „Gotowe”; jest tam, to obiekt, to jest singleton, a jego nazwa oznacza „brak”, a nie jest to nadużywany None (który mógłby zostać umieszczony w kolejce jako część normalnego przepływu danych). YMMV.

tzot
źródło
14
Czy nie byłoby jaśniej powiedzieć gdzieś: „Gotowe = obiekt ()” i po prostu tego użyć?
Brandon Rhodes
12
Niekoniecznie - wymaga, abyś faktycznie gdzieś powiedział Done = object (). Wartości Sentinel niekoniecznie są złe - a używanie prawie bezużytecznych singletonów Pythona jako wartowników nie jest tak okropne IMO (wielokropek i () to te, których użyłem, gdzie Żaden nie byłby mylący).
Rick Copeland
6
Jeśli chodzi o Done = object (), myślę, że używanie wielokropka jest lepsze, zwłaszcza jeśli używasz go do komunikacji z kolejkami. Jeśli przejdziesz od komunikacji wewnątrz wątku do komunikacji wewnątrzprocesowej, identyfikator (Gotowe) nie będzie taki sam w innym procesie i nie ma nic, co odróżnia jeden obiekt od drugiego. Identyfikator wielokropka też nie będzie taki sam, ale przynajmniej typ będzie taki sam - o to chodzi w singletonie.
Tristan Reid
Pytanie brzmi „Jak używasz wielokropka”, ale wydaje mi się, że źle to odebrałeś. Ma wiele interpretacji. Ale myślę, że poprawna odpowiedź brzmi: „Jak używa się wielokropka?” tj. „Jakie kroki powinienem podjąć, aby użyć wielokropka we własnym kodzie”.
Lyndon White,
6

Jak stwierdzono w innych odpowiedziach, można go używać do tworzenia plasterków. Przydatne, gdy nie chcesz pisać wielu notacji z pełnymi wycinkami ( :) lub gdy po prostu nie jesteś pewien, jaka jest wymiarowość manipulowanej tablicy.

To, co uważałem za ważne, aby podkreślić, a czego brakowało w innych odpowiedziach, to fakt, że można go użyć nawet wtedy, gdy nie ma więcej wymiarów do wypełnienia.

Przykład:

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

Spowoduje to błąd:

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

To zadziała:

a[...,0,:]
array([0, 1])
Mauricio Perez
źródło