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.
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şkiDilimleme 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.
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.
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-1
den 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)'