Dilim gösterimini anlama

Python'un dilim gösterimi hakkında iyi bir açıklamaya ihtiyacım var (referanslar bir artıdır).

Bana göre bu notasyonun biraz toparlanması gerekiyor.

Son derece güçlü görünüyor, ancak kafamda tam olarak oturtamadım.

Çözüm

Aslında oldukça basit:

a[start:stop]  # items start through stop-1
a[start:]      # items start through the rest of the array
a[:stop]       # items from the beginning through stop-1
a[:]           # a copy of the whole array

Yukarıdakilerden herhangi biriyle birlikte kullanılabilen step değeri de vardır:

a[start:stop:step] # start through not past stop, by step

Hatırlanması gereken kilit nokta, :stop değerinin seçilen dilimde olmayan ilk değeri temsil ettiğidir. Dolayısıyla, stop ve start arasındaki fark seçilen öğe sayısıdır (eğer step varsayılan olarak 1 ise).

Diğer bir özellik ise start veya stop negatif bir sayı olabilir, yani dizinin başı yerine sonundan itibaren sayar. Yani:

a[-1]    # last item in the array
a[-2:]   # last two items in the array
a[:-2]   # everything except the last two items

Benzer şekilde, step negatif bir sayı olabilir:

a[::-1]    # all items in the array, reversed
a[1::-1]   # the first two items, reversed
a[:-3:-1]  # the last two items, reversed
a[-3::-1]  # everything except the last two items, reversed

Python, istediğinizden daha az öğe varsa programcıya karşı naziktir. Örneğin, a[:-2] isterseniz ve a sadece bir eleman içeriyorsa, hata yerine boş bir liste alırsınız. Bazen hatayı tercih edersiniz, bu yüzden bunun olabileceğinin farkında olmalısınız.

slice() nesnesi ile ilişki

Dilimleme operatörü [] aslında yukarıdaki kodda : notasyonu (sadece [] içinde geçerlidir) kullanılarak bir slice() nesnesi ile kullanılmaktadır, yani:

a[start:stop:step]

eşdeğerdir:

a[slice(start, stop, step)]

Slice nesneleri de range()a benzer şekilde argüman sayısına bağlı olarak biraz farklı davranır, yani hem slice(stop) hem de slice(start, stop[, step]) desteklenir. Belirli bir argümanı belirtmeyi atlamak için None kullanılabilir, böylece örneğin a[start:], a[slice(start, None)] veya a[::-1], a[slice(None, None, -1)] ile eşdeğerdir.

Basit dilimleme için : tabanlı gösterim çok yararlı olsa da, slice() nesnelerinin açık kullanımı dilimlemenin programatik olarak oluşturulmasını basitleştirir.

Yorumlar (7)

Python öğreticisi]1 bundan bahsediyor (dilimleme ile ilgili kısma gelene kadar biraz aşağı kaydırın).

ASCII sanat diyagramı da dilimlerin nasıl çalıştığını hatırlamak için yararlıdır:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

Dilimlerin nasıl çalıştığını hatırlamanın bir yolu, indisleri karakterler arasında işaret ediyor gibi düşünmektir, ilk karakterin sol kenarı 0 olarak numaralandırılır. Daha sonra n karakterlik bir dizenin son karakterinin sağ kenarı n indisine sahiptir.

Yorumlar (2)

Dilbilgisi tarafından izin verilen olasılıkların sıralanması:

>>> seq[:]                # [seq[0],   seq[1],          ..., seq[-1]    ]
>>> seq[low:]             # [seq[low], seq[low+1],      ..., seq[-1]    ]
>>> seq[:high]            # [seq[0],   seq[1],          ..., seq[high-1]]
>>> seq[low:high]         # [seq[low], seq[low+1],      ..., seq[high-1]]
>>> seq[::stride]         # [seq[0],   seq[stride],     ..., seq[-1]    ]
>>> seq[low::stride]      # [seq[low], seq[low+stride], ..., seq[-1]    ]
>>> seq[:high:stride]     # [seq[0],   seq[stride],     ..., seq[high-1]]
>>> seq[low:high:stride]  # [seq[low], seq[low+stride], ..., seq[high-1]]

Elbette, (yüksek-düşük)%stride != 0 ise, bitiş noktası yüksek-1den biraz daha düşük olacaktır.

Eğer stride negatif ise, geri sayım yaptığımız için sıralama biraz değişir:

>>> seq[::-stride]        # [seq[-1],   seq[-1-stride],   ..., seq[0]    ]
>>> seq[high::-stride]    # [seq[high], seq[high-stride], ..., seq[0]    ]
>>> seq[:low:-stride]     # [seq[-1],   seq[-1-stride],   ..., seq[low+1]]
>>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]]

Genişletilmiş dilimleme (virgüller ve elipsler ile) çoğunlukla sadece özel veri yapıları (NumPy gibi) tarafından kullanılır; temel diziler bunları desteklemez.

>>> class slicee:
...     def __getitem__(self, item):
...         return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
Yorumlar (3)