Python'da üç nokta dilimleme sözdizimini nasıl kullanırsınız?


Yanıtlar:


102

Ellipsisveya ... gizli bir özellik değil, yalnızca sabittir. Diyelim ki javascript ES6, dil sözdiziminin bir parçası. Hiçbir yerleşik sınıf veya Python dil yapısı bunu kullanmaz.

Yani sözdizimi tamamen size veya başkasına, onu anlamak için kod yazmış olmanıza bağlıdır.

Numpy bunu dokümanlarda belirtildiği gibi kullanır . Burada bazı örnekler .

Kendi sınıfınızda şu şekilde kullanırsınız:

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

Tabii ki, python belgeleri ve dil referansı var . Ama bunlar pek yardımcı değil.


6
tüm öğeleri söylemek için "propper" yolu >>> x [:] >>> x [:, 1: 2]
Ronny

30
@Ronny: Mesele, Elipsilerin bazı özel kullanımlarını göstermekti.
nosklo

7
Bağlantılar kopmuş gibi görünüyor.
SwiftsNamesake

231

Üç nokta yüksek boyutlu veri yapılarını dilimlemek için numpy'de kullanılır.

Demek için tasarlanmış , bu noktada birçok tam dilimler (olarak eklemek :) tüm boyutları çok boyutlu dilim uzatmak için .

Örnek :

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

Şimdi, 2x2x2x2 boyutunda 4 boyutlu bir matrisiniz var. 4. boyuttaki tüm ilk öğeleri seçmek için üç nokta gösterimini kullanabilirsiniz

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

eşdeğer

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

Kendi uygulamalarınızda, yukarıda belirtilen sözleşmeyi görmezden gelebilir ve uygun gördüğünüz şekilde kullanabilirsiniz.


Belki yanılıyorum ama a[:,:,:,0]bir kopya a[...,0]döndürecek ve kopya değil "görünüm" döndürecek değil mi? id()Hem sürümleri hem de 3-dim dizi için çalışan denedim : a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] tüm farklı kimlikleri varken: a[..., 0], a[..., 1], a[..., 2] tüm aynı kimlikleri var.
mohitsharma44

@ mohitsharma44 makinemde değil;) id()her ikisi için de aynı değeri döndürür. Ayrıca ile kontrol etmek __array_interface__['data']aynı bellek adresini gösterir.
BoltzmannBrain

Kullanabileceğimizi görüyorum a[indexes, ...] bir 1-dimenstional dizi bile iken!
acgtyrant

1
Elipsler sıfır boyutlu veri yapıları için de yararlıdır. Skaler numpy.ndarrays'e yazmayı bildiğim tek yol bunlar, örneğin: my_scalar = np.asarray (3); my_scalar [...] = 5. my_scalar [:] = 5 yaparsanız, haklı olarak bir hata alırsınız, çünkü yinelenecek: için 0 boyutu yoktur.
SuperElectric

1
@SuperElectric Ayrıca my_scalar.itemset (scalarvalue) kullanabilirsiniz. Tabii ki, my_scalar [...] = scalar_value daha kısadır, ancak yukarıdaki yorumda bunu bilmenin tek yolu olduğunu söylediniz. Sadece bir alternatif veriyorum.
kamathln

70

Bu, dilimleri ile ilgisi olmayan Elipsis için başka bir kullanımdır: Sıklıkla kuyruklarla iplik içi iletişimde, "Bitti" sinyalini veren bir işaret olarak kullanıyorum; orada, bu bir nesne, bu bir singleton ve adı "yok" anlamına geliyor ve aşırı kullanılmış Yok (normal veri akışının bir parçası olarak bir sıraya konabilir). YMMV.


14
Bir yerde "Bitti = nesne ()" demek ve bunu kullanmak daha açık olamaz mı?
Brandon Rhodes

12
İlle - bu aslında gerektirir demek = nesneyi () bir yerlerde Yapıldı. Sentinel değerleri mutlaka kötü bir şey değildir - ve sentinel olarak neredeyse işe yaramaz Python singletonları kullanmak o kadar korkunç IMO değildir (Elips ve () Hiçbiri'nin kafa karıştırıcı olduğu yerlerde kullandığım).
Rick Copeland

6
Done = object () ile ilgili olarak, özellikle kuyruklarla iletişim için kullanıyorsanız Elipsis'i kullanmak daha iyidir. Eğer iplik içi işlemden süreç içi iletişime geçerseniz id (Done) diğer süreçte aynı olmaz ve bir nesneyi diğerinden ayıracak hiçbir şey yoktur. Üç nokta kimliği de aynı olmayacak, ama en azından tip aynı olacak - bu bir singleton'un noktası.
Tristan Reid

Soruda "üç nokta nasıl kullanıyorsunuz" yazıyor ama buna yanlış baktığınıza inanıyorum. Birçok yorumu var. Ama bence doğru olan: "Elips nasıl kullanılır?" yani "Elipsimi kendi kodumda kullanmak için hangi adımları atmalıyım?".
Lyndon White

6

Diğer cevaplarda belirtildiği gibi, dilim oluşturmak için kullanılabilir. Çok sayıda tam dilim gösterimi ( :) yazmak istemediğinizde veya değiştirilen dizinin boyutunun ne olduğundan emin değilseniz kullanışlıdır.

Vurgulamak için önemli olduğunu düşündüğüm ve diğer cevaplarda eksik olan şey, doldurulacak daha fazla boyut olmasa bile kullanılabileceğidir.

Misal:

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

Bu hataya neden olur:

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

Bu çalışacak:

a[...,0,:]
array([0, 1])
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.