Yanıtlar:
Gerçekten 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
step
Yukarıdakilerin herhangi biriyle kullanılabilecek bir değer de vardır :
a[start:stop:step] # start through not past stop, by step
Hatırlanması gereken kilit nokta, :stop
değerin seçilen dilimde olmayan ilk değeri temsil etmesidir. Bu nedenle, arasındaki fark stop
ve start
(eğer seçilen elemanlarının sayısı step
1, varsayılan).
Diğer bir özellik olduğunu start
veya stop
bir olabilir negatif yerine başlangıçta dizisinin ucundan sayar aracı sayısı. 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
İstediğinizden daha az öğe varsa, Python programcıya karşı naziktir. Örneğin, yalnızca bir öğe istiyor a[:-2]
ve a
hata içeriyorsa, hata yerine boş bir liste alırsınız. Bazen hatayı tercih edersiniz, bu yüzden bunun olabileceğini bilmeniz gerekir.
slice()
Nesne ile ilişkiDilimleme operatörü []
aslında yukarıdaki kodda (sadece içinde geçerli olan ) gösterimi slice()
kullanan bir nesne ile kullanılır , yani::
[]
a[start:stop:step]
şuna eşittir:
a[slice(start, stop, step)]
Dilim nesneleri, bağımsız değişkenlerin sayısına bağlı olarak range()
, yani her ikisine de benzer şekilde biraz farklı davranır slice(stop)
ve slice(start, stop[, step])
desteklenir. Belirli bir bağımsız değişkeni belirtmeyi atlamak için, biri kullanılabilir None
; böylece örneğin a[start:]
, eşdeğer a[slice(start, None)]
veya a[::-1]
eşdeğerdir a[slice(None, None, -1)]
.
:
Tabanlı gösterim basit dilimleme için çok yararlı olsa da , slice()
nesnelerin açık kullanımı programlı dilimlemeyi kolaylaştırır.
None
boş alanların herhangi birini değiştirebilirsiniz . Örneğin [None:None]
bir kopyasını yapar. Bir değişken kullanarak aralığın sonunu belirtmeniz ve son öğeyi eklemeniz gerektiğinde yararlıdır.
del
wrt dilim gösterimi yapar. Özellikle, del arr[:]
hemen belli değil ("arr [:] bir kopyasını çıkarıyor, o yüzden del bu kopyayı sil ???" vb.)
Python öğretici bu konuda görüşmeler (biraz aşağı kaydırma sen dilimleme ilgili kısma elde edene kadar).
ASCII sanat diyagramı, dilimlerin nasıl çalıştığını hatırlamak için de yararlıdır:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
Dilimler çalışma işaret olarak endeksleri düşünmek için ne kadar hatırlamak bir yolu arasındaki ilk karakterin sol kenarı ile, karakterlerin Sonra bir dizenin son karakterinin sağ kenarı 0'a sayılı n karakterleri dizini vardır n .
a[-4,-6,-1]
olmak yP
ama öyle ty
. Her zaman işe yarayan şey, karakterlerde veya yuvalarda düşünmek ve dizine eklemeyi yarı açık bir aralık olarak kullanmaktır - pozitif adım ise sağ açık, negatif adım ise sola açık.
x[:0]
en baştan başlarken olduğu gibi ), bu nedenle özel durumdaki küçük dizileri kullanmanız gerekir. : /
Dilbilgisinin izin verdiği olasılıkların numaralandırılması:
>>> 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]]
Tabii ki, eğer (high-low)%stride != 0
, o zaman son nokta biraz daha düşük olacaktır high-1
.
Eğer stride
negatifse, sipariş biraz değişti beri aşağı bizler sayma:
>>> 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ül ve elipslerle) çoğunlukla yalnızca özel veri yapıları (NumPy gibi) tarafından kullanılır; temel diziler onları 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)'
repr
__getitem__
; örneğiniz buna eşdeğerdir apple[slice(4, -4, -1)]
.
Yukarıdaki cevaplar dilim atamasını tartışmıyor. Dilim atamasını anlamak için ASCII sanatına başka bir konsept eklemek yararlıdır:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
Slice position: 0 1 2 3 4 5 6
Index position: 0 1 2 3 4 5
>>> p = ['P','y','t','h','o','n']
# Why the two sets of numbers:
# indexing gives items, not lists
>>> p[0]
'P'
>>> p[5]
'n'
# Slicing gives lists
>>> p[0:1]
['P']
>>> p[0:2]
['P','y']
Bir sezgisel tarama, sıfırdan n'ye bir dilim için şunu düşünün: "sıfır başlangıçtır, başlangıçta başlar ve bir listede n öğe alır".
>>> p[5] # the last of six items, indexed from zero
'n'
>>> p[0:5] # does NOT include the last item!
['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
['P','y','t','h','o','n']
Başka bir sezgisel tarama, "herhangi bir dilim için, başlangıcı sıfırla değiştirin, listenin sonunu almak için önceki sezgisel yöntemi uygulayın, ardından öğeleri başlangıçtan kesmek için ilk sayıyı tekrar sayın" dır.
>>> p[0:4] # Start at the beginning and count out 4 items
['P','y','t','h']
>>> p[1:4] # Take one item off the front
['y','t','h']
>>> p[2:4] # Take two items off the front
['t','h']
# etc.
Dilim ödevin ilk kuralı dilimleme beri olmasıdır döndüren bir liste, dilim atama gerektirir bir liste (veya başka iterable):
>>> p[2:3]
['t']
>>> p[2:3] = ['T']
>>> p
['P','y','T','h','o','n']
>>> p[2:3] = 't'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
Yukarıda da görebileceğiniz ikinci dilim atama kuralı, listenin hangi bölümünün dilim dizinleme ile döndürüldüğü, dilim atamasıyla değiştirilen bölümle aynı olmasıdır:
>>> p[2:4]
['T','h']
>>> p[2:4] = ['t','r']
>>> p
['P','y','t','r','o','n']
Dilim atamasının üçüncü kuralı, atanan listenin (yinelenebilir) aynı uzunlukta olması gerekmediğidir; endekslenen dilim basitçe dilimlenir ve atanan her şeyle toplu olarak değiştirilir:
>>> p = ['P','y','t','h','o','n'] # Start over
>>> p[2:4] = ['s','p','a','m']
>>> p
['P','y','s','p','a','m','o','n']
Alışmak için en zor kısım boş dilimlere atamadır. Sezgisel 1 ve 2'yi kullanarak başınızı boş bir dilimi dizine eklemek kolaydır :
>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
['P','y','t','h']
>>> p[1:4]
['y','t','h']
>>> p[2:4]
['t','h']
>>> p[3:4]
['h']
>>> p[4:4]
[]
Ve sonra bunu gördükten sonra, boş dilime dilim ataması da mantıklı:
>>> p = ['P','y','t','h','o','n']
>>> p[2:4] = ['x','y'] # Assigned list is same length as slice
>>> p
['P','y','x','y','o','n'] # Result is same length
>>> p = ['P','y','t','h','o','n']
>>> p[3:4] = ['x','y'] # Assigned list is longer than slice
>>> p
['P','y','t','x','y','o','n'] # The result is longer
>>> p = ['P','y','t','h','o','n']
>>> p[4:4] = ['x','y']
>>> p
['P','y','t','h','x','y','o','n'] # The result is longer still
Dilimin (4) ikinci sayısını değiştirmediğimizden, boş dilime atadığımızda bile, eklenen öğelerin her zaman 'o' değerine doğru istiflendiğini unutmayın. Dolayısıyla, boş dilim atamasının konumu, boş olmayan dilim atamalarının konumlarının mantıksal uzantısıdır.
Biraz yedekleme, dilim başlangıcını sayma alayımıza devam ettiğinizde ne olur?
>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
['P','y','t','h']
>>> p[1:4]
['y','t','h']
>>> p[2:4]
['t','h']
>>> p[3:4]
['h']
>>> p[4:4]
[]
>>> p[5:4]
[]
>>> p[6:4]
[]
Dilimleme ile işiniz bittiğinde işiniz bitti; geriye doğru dilimlemeye başlamaz. Python'da, negatif bir sayı kullanarak açıkça istemediğiniz sürece negatif adımlar alamazsınız.
>>> p[5:3:-1]
['n','o']
"İşiniz bittiğinde, işiniz bitti" kuralının bazı garip sonuçları vardır:
>>> p[4:4]
[]
>>> p[5:4]
[]
>>> p[6:4]
[]
>>> p[6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
Aslında, endekslemeye kıyasla, Python dilimleme tuhaf bir şekilde hataya dayanıklıdır:
>>> p[100:200]
[]
>>> p[int(2e99):int(1e99)]
[]
Bu bazen kullanışlı olabilir, ancak biraz garip davranışlara da yol açabilir:
>>> p
['P', 'y', 't', 'h', 'o', 'n']
>>> p[int(2e99):int(1e99)] = ['p','o','w','e','r']
>>> p
['P', 'y', 't', 'h', 'o', 'n', 'p', 'o', 'w', 'e', 'r']
Uygulamanıza bağlı olarak, bu sizin için umduğunuz şey olabilir ... ya da olmayabilir!
Aşağıda orijinal cevabımın metni verilmiştir. Birçok insan için yararlı oldu, bu yüzden silmek istemedim.
>>> r=[1,2,3,4]
>>> r[1:1]
[]
>>> r[1:1]=[9,8]
>>> r
[1, 9, 8, 2, 3, 4]
>>> r[1:1]=['blah']
>>> r
[1, 'blah', 9, 8, 2, 3, 4]
Bu, dilimleme ve dizine ekleme arasındaki farkı da netleştirebilir.
Python'un dilim gösterimini açıklayın
Kısaca, iki nokta ( :
simge gösterimde) ( subscriptable[subscriptarg]
) yapmak dilim notasyonu - isteğe bağlı bağımsız değişkenler, start
, stop
, step
:
sliceable[start:stop:step]
Python dilimleme, verilerinizin bölümlerine yöntemsel olarak erişmenin hesaplamalı olarak hızlı bir yoludur. Bence, bir ara Python programcısı olmak için, dilin aşina olması gereken bir yönü.
Başlamak için birkaç terim tanımlayalım:
start: Dilimin başlangıç dizini, stop ile aynı değilse , varsayılan olarak 0, yani ilk dizinde olmadığı sürece bu dizindeki öğeyi içerecektir . Negatifse,
n
öğeleri en baştan başlatmak anlamına gelir .Dur: dilimin bitiş endeksi, bu yok değil , dizinin uzunluğu varsayılan kadar olduğunu, dilimlenmiş ve sonunu da dahil olmak bu endeksi de eleman bulunmaktadır.
adım: dizinin arttığı miktar, varsayılan değer 1'dir. Negatifse, yinelenebilir öğeyi tersine dilimliyorsunuz.
Bu pozitif veya negatif sayılardan herhangi birini yapabilirsiniz. Pozitif sayılar anlamı basittir, ancak negatif sayılar için, sadece Python endeksler gibi, sizin için ucundan geriye doğru saymak başlangıcında ve durdurmak ve için adım , sadece Endeksinizi azaltma. Bu örnek belgelerin öğreticisinden , ancak her dizinde hangi öğenin başvurduğunu belirtmek için biraz değiştirdim:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
Dilim notasyonunu destekleyen bir sekansla kullanmak için, sekansı takip eden köşeli parantezlere en az bir kolon eklemelisiniz (aslında Python veri modeline göre sekansın yöntemini uygular__getitem__
).
Dilim notasyonu şu şekilde çalışır:
sequence[start:stop:step]
Ve başlangıç , durdurma ve adım için varsayılanlar olduğunu hatırlayın , bu yüzden varsayılanlara erişmek için argümanı dışarıda bırakın.
Bir listeden son dokuz öğeyi (ya da dizeyi destekleyen başka bir diziyi) almak için dilim gösterimi şöyle görünür:
my_list[-9:]
Bunu gördüğümde, köşeli parantez içindeki parçayı "uçtan uca 9." olarak okudum. (Aslında, bunu zihinsel olarak "-9, açık" olarak kısaltırım)
Tam gösterim
my_list[-9:None:None]
ve varsayılanları değiştirmek için (aslında step
negatif olduğunda , stop
varsayılanı varsayılan -len(my_list) - 1
, bu yüzden None
durmak gerçekten hangi son adımın götürdüğü anlamına gelir):
my_list[-9:len(my_list):1]
İki nokta üst üste , :
Python'a normal bir dizin değil, bir dilim verdiğinizi söyleyen şeydir. Bu yüzden Python 2'deki listelerin sığ bir kopyasını oluşturmanın deyimsel yolu
list_copy = sequence[:]
Ve onları temizlemek:
del my_list[:]
(Python 3 bir list.copy
ve list.clear
yöntemi alır .)
step
negatif için varsayılan olduğunu start
ve stop
değişimVarsayılan olarak, step
bağımsız değişken boşsa (veya None
), atanır +1
.
Ancak negatif bir tamsayı geçebilirsiniz ve liste (veya diğer standart dilimlenebilirler) baştan sona dilimlenir.
Böylece negatif bir dilim start
ve stop
!
Kullanıcıları kaynakların yanı sıra belgeleri okumaya teşvik etmek istiyorum. Dilim için kaynak kodu nesneleri ve bu mantık burada bulunur . İlk önce step
negatif olup olmadığını belirleriz :
step_is_negative = step_sign < 0;
Eğer öyleyse, alt sınır, -1
başlangıca kadar ve sonuna kadar dilimlediğimiz anlamına gelir ve üst sınır uzunluk eksi 1'dir, yani sonunda başlıyoruz. (Not Bunun semantik yani -1
olan farklı bir gelen -1
kullanıcıların son öğeyi gösteren Python endeksler geçmesi olabilir.)
if (step_is_negative) { lower = PyLong_FromLong(-1L); if (lower == NULL) goto error; upper = PyNumber_Add(length, lower); if (upper == NULL) goto error; }
Aksi takdirde step
pozitiftir ve alt sınır sıfır ve üst sınır dilimlenmiş listenin uzunluğuna (ki buna kadar gidip dahil değiliz) olacaktır.
else { lower = _PyLong_Zero; Py_INCREF(lower); upper = length; Py_INCREF(upper); }
Ardından, start
ve için varsayılan değerleri uygulamamız gerekebilir stop
- - negatif start
ise , varsayılan değer için üst sınır olarak hesaplanır step
:
if (self->start == Py_None) { start = step_is_negative ? upper : lower; Py_INCREF(start); }
ve stop
alt sınır:
if (self->stop == Py_None) { stop = step_is_negative ? lower : upper; Py_INCREF(stop); }
Dilimi oluşturmanın, list.__getitem__
yöntemi yönteme geçirmekten ayırmak yararlı olabilir ( köşeli parantez budur ). Yeni olmasanız bile, kodunuzu daha okunaklı tutar, böylece kodunuzu okumak zorunda kalabilecekler ne yaptığınızı daha kolay anlayabilir.
Ancak, bir değişkene iki nokta üst üste işaretiyle ayrılmış bazı tamsayılar atayamazsınız. Dilim nesnesini kullanmanız gerekir:
last_nine_slice = slice(-9, None)
İkinci bağımsız değişken, None
ilk değişken olarak yorumlanır, böylece, gerekli olan start
değişken , aksi olurdu stop
argüman .
Daha sonra dilim nesnesini sıranıza iletebilirsiniz:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
Aralıkların da dilim alması ilginçtir:
>>> range(100)[last_nine_slice]
range(91, 100)
Python listelerinin dilimleri bellekte yeni nesneler oluşturduğundan, dikkat edilmesi gereken bir başka önemli işlev de vardır itertools.islice
. Tipik olarak, sadece bellekte statik olarak oluşturulmasını sağlamakla kalmayıp bir dilim üzerinde yineleme yapmak istersiniz. islice
bunun için mükemmel. Bir yetersizlik, bu olumsuz argümanlar desteklemez start
, stop
veya step
, bu bir sorun yani eğer endekslerini hesaplamak veya önceden iterable ters gerekebilir.
length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)
ve şimdi:
>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]
Liste dilimlerinin bir kopya oluşturması, listelerin kendilerinin bir özelliğidir. Bir Pandas DataFrame gibi gelişmiş nesneleri dilimliyorsanız, kopya yerine orijinal görünümüne dönebilir.
Dilimleme sözdizimini ilk gördüğümde benim için hemen belirgin olmayan birkaç şey:
>>> x = [1,2,3,4,5,6]
>>> x[::-1]
[6,5,4,3,2,1]
Dizileri tersine çevirmenin kolay yolu!
Ve eğer herhangi bir nedenle, ters sırayla her ikinci öğeyi istiyorsanız:
>>> x = [1,2,3,4,5,6]
>>> x[::-2]
[6,4,2]
Python 2.7 sürümünde
Python'da dilimleme
[a:b:c]
len = length of string, tuple or list
c -- default is +1. The sign of c indicates forward or backward, absolute value of c indicates steps. Default is forward with step size 1. Positive means forward, negative means backward.
a -- When c is positive or blank, default is 0. When c is negative, default is -1.
b -- When c is positive or blank, default is len. When c is negative, default is -(len+1).
Dizin atamasını anlamak çok önemlidir.
In forward direction, starts at 0 and ends at len-1
In backward direction, starts at -1 and ends at -len
[A: b: c] dediğinizde, c (ileri veya geri) işaretine bağlı olarak, a ile başlayın ve b ile bitirin (bth dizinindeki öğe hariç). Yukarıdaki dizine ekleme kuralını kullanın ve yalnızca bu aralıktaki öğeleri bulacağınızı unutmayın:
-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1
Ancak bu aralık her iki yönde sonsuz olarak devam eder:
...,-len -2 ,-len-1,-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1, len, len +1, len+2 , ....
Örneğin:
0 1 2 3 4 5 6 7 8 9 10 11
a s t r i n g
-9 -8 -7 -6 -5 -4 -3 -2 -1
A, b ve c seçiminiz yukarıdaki a, b, c kurallarını kullanarak geçiş yaparken yukarıdaki aralıkla çakışmaya izin veriyorsa, öğeleri (bir geçiş sırasında dokundu) içeren bir liste alırsınız veya boş bir liste alırsınız.
Son bir şey: a ve b eşitse, boş bir liste alırsınız:
>>> l1
[2, 3, 4]
>>> l1[:]
[2, 3, 4]
>>> l1[::-1] # a default is -1 , b default is -(len+1)
[4, 3, 2]
>>> l1[:-4:-1] # a default is -1
[4, 3, 2]
>>> l1[:-3:-1] # a default is -1
[4, 3]
>>> l1[::] # c default is +1, so a default is 0, b default is len
[2, 3, 4]
>>> l1[::-1] # c is -1 , so a default is -1 and b default is -(len+1)
[4, 3, 2]
>>> l1[-100:-200:-1] # Interesting
[]
>>> l1[-1:-200:-1] # Interesting
[4, 3, 2]
>>> l1[-1:-1:1]
[]
>>> l1[-1:5:1] # Interesting
[4]
>>> l1[1:-7:1]
[]
>>> l1[1:-7:-1] # Interesting
[3, 2]
>>> l1[:-2:-2] # a default is -1, stop(b) at -2 , step(c) by 2 in reverse direction
[4]
a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]; a[:-2:-2]
Hangisi[9]
Bu harika tabloyu http://wiki.python.org/moin/MovingToPythonFromOtherLanguages adresinde buldum
Python indexes and slices for a six-element list.
Indexes enumerate the elements, slices enumerate the spaces between the elements.
Index from rear: -6 -5 -4 -3 -2 -1 a=[0,1,2,3,4,5] a[1:]==[1,2,3,4,5]
Index from front: 0 1 2 3 4 5 len(a)==6 a[:5]==[0,1,2,3,4]
+---+---+---+---+---+---+ a[0]==0 a[:-2]==[0,1,2,3]
| a | b | c | d | e | f | a[5]==5 a[1:2]==[1]
+---+---+---+---+---+---+ a[-1]==5 a[1:-1]==[1,2,3,4]
Slice from front: : 1 2 3 4 5 : a[-2]==4
Slice from rear: : -5 -4 -3 -2 -1 :
b=a[:]
b==[0,1,2,3,4,5] (shallow copy of a)
Biraz kullandıktan sonra en basit açıklamanın bir for
döngüdeki argümanlar ile tam olarak aynı olduğunu anlıyorum ...
(from:to:step)
Bunlardan herhangi biri isteğe bağlıdır:
(:to:step)
(from::step)
(from:to)
Daha sonra negatif indeksleme, dizeyi anlamak için negatif indekslere eklemeniz yeterlidir.
Bu zaten benim için çalışıyor ...
Nasıl çalıştığını hatırlamayı daha kolay buluyorum ve sonra herhangi bir belirli başlatma / durdurma / adım kombinasyonunu bulabilirim.
İlk range()
önce anlamak öğretici :
def range(start=0, stop, step=1): # Illegal syntax, but that's the effect
i = start
while (i < stop if step > 0 else i > stop):
yield i
i += step
Başlayarak start
, artırarak step
ulaşmayın stop
. Çok basit.
Olumsuz adım hakkında hatırlanması gereken şey stop
, ister daha yüksek ister daha düşük olsun, her zaman hariç tutulan sondur. Aynı dilimi ters sırayla istiyorsanız, tersine çevirmeyi ayrı ayrı yapmak çok daha temizdir: örneğin, 'abcde'[1:-2][::-1]
bir karakteri soldan, ikisini sağdan dilimler, sonra ters çevirir. (Ayrıca bakınız reversed()
.)
Dizi dilimleme aynıdır, ancak önce negatif dizinleri normalleştirir ve asla dizinin dışına çıkamaz:
YAPILACAKLAR : Aşağıdaki kod, abs (adım)> 1 olduğunda "dizinin dışına asla çıkma" ile ilgili bir hataya sahiptir; Ben düşünüyorum ben doğru gibi yamalı ama anlamak zordur.
def this_is_how_slicing_works(seq, start=None, stop=None, step=1):
if start is None:
start = (0 if step > 0 else len(seq)-1)
elif start < 0:
start += len(seq)
if not 0 <= start < len(seq): # clip if still outside bounds
start = (0 if step > 0 else len(seq)-1)
if stop is None:
stop = (len(seq) if step > 0 else -1) # really -1, not last element
elif stop < 0:
stop += len(seq)
for i in range(start, stop, step):
if 0 <= i < len(seq):
yield seq[i]
is None
Ayrıntılar için endişelenmeyin - unutmayın, start
ve / veya stop
her zaman size tüm diziyi vermek için doğru olanı yapın.
Negatif indekslerin normalleştirilmesi ilk olarak başlangıç ve / veya durdurmanın uçtan bağımsız olarak sayılmasına izin verir: 'abcde'[1:-2] == 'abcde'[1:3] == 'bc'
rağmen range(1,-2) == []
. Normalleştirme bazen "uzunluk modulo" olarak düşünülür, ancak uzunluğu sadece bir kez eklediğine dikkat edin: örneğin 'abcde'[-53:42]
sadece tüm dizedir.
this_is_how_slicing_works
Piton dilim ile aynı değildir. EG python'da [0, 1, 2][-5:3:3]
[0] alacak, ancak list(this_is_how_slicing_works([0, 1, 2], -5, 3, 3))
[1] alacaktır.
range(4)[-200:200:3] == [0, 3]
ama list(this_is_how_slicing_works([0, 1, 2, 3], -200, 200, 3)) == [2]
. Benim if 0 <= i < len(seq):
"dizinin dışına asla çıkma" özelliğini uygulamak için bir girişimim oldu, ancak> 1. Adım için yanlış. Bugün daha sonra tekrar yazacağım (testlerle).
"Öğeler arasında bir dizin noktaları" yöntemini kendim hakkında düşünme yöntemini kullanıyorum, ancak bazen başkalarının almasına yardımcı olan bunu tanımlamanın bir yolu şudur:
mylist[X:Y]
X, istediğiniz ilk öğenin dizinidir.
Y ilk elemanın endeksidir yok istiyorum.
Index:
------------>
0 1 2 3 4
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
0 -4 -3 -2 -1
<------------
Slice:
<---------------|
|--------------->
: 1 2 3 4 :
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
: -4 -3 -2 -1 :
|--------------->
<---------------|
Umarım bu listeyi Python'da modellemenize yardımcı olur.
Referans: http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
Python dilimleme notasyonu:
a[start:end:step]
start
ve end
negatif değerler dizisinin sonuna göre olarak yorumlanır.end
dahil edilecek son elemandan sonraki pozisyonu belirtir .[+0:-0:1]
.start
veend
Gösterim (numpy) matrislere ve çok boyutlu dizilere uzanır. Örneğin, tüm sütunları dilimlemek için şunları kullanabilirsiniz:
m[::,0:2:] ## slice the first two columns
Dilimler, dizi öğelerinin kopyalarını değil referanslarını tutar. Bir diziyi ayrı bir kopya yapmak istiyorsanız, kullanabilirsiniz deepcopy()
.
Bu sadece bazı ekstra bilgiler içindir ... Aşağıdaki listeyi düşünün
>>> l=[12,23,345,456,67,7,945,467]
Listeyi tersine çevirmek için birkaç başka numara:
>>> l[len(l):-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[len(l)::-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[::-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[-1:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
Yeni başlayanlara dilleri şu şekilde öğretiyorum:
Dizin oluşturma ve dilimleme arasındaki farkı anlama:
Wiki Python, indeksleme ve dilimlemeyi açıkça ayıran bu muhteşem resme sahiptir.
İçinde altı element bulunan bir listedir. Dilimlemeyi daha iyi anlamak için, bu listeyi birlikte yerleştirilmiş altı kutudan oluşan bir set olarak düşünün. Her kutunun içinde bir alfabe vardır.
Dizinleme, kutunun içeriğiyle uğraşmak gibidir. Herhangi bir kutunun içeriğini kontrol edebilirsiniz. Ancak aynı anda birden fazla kutunun içeriğini kontrol edemezsiniz. Kutunun içindekileri bile değiştirebilirsiniz. Ancak bir kutuya iki top koyamaz ya da aynı anda iki topu değiştiremezsiniz.
In [122]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [123]: alpha
Out[123]: ['a', 'b', 'c', 'd', 'e', 'f']
In [124]: alpha[0]
Out[124]: 'a'
In [127]: alpha[0] = 'A'
In [128]: alpha
Out[128]: ['A', 'b', 'c', 'd', 'e', 'f']
In [129]: alpha[0,1]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-129-c7eb16585371> in <module>()
----> 1 alpha[0,1]
TypeError: list indices must be integers, not tuple
Dilimleme kutuları kendileriyle uğraşmak gibidir. İlk kutuyu alıp başka bir masaya yerleştirebilirsiniz. Kutuyu almak için bilmeniz gereken tek şey kutunun başlangıç ve bitiş konumudur.
Hatta ilk üç kutuyu veya son iki kutuyu veya 1 ve 4 arasındaki tüm kutuları da alabilirsiniz. Böylece, başlangıç ve bitiş bilgisini biliyorsanız herhangi bir kutu setini seçebilirsiniz. Bu konumlara başlatma ve durdurma konumları denir.
İlginç olan, aynı anda birden fazla kutuyu değiştirebilmenizdir. Ayrıca istediğiniz yere birden fazla kutu yerleştirebilirsiniz.
In [130]: alpha[0:1]
Out[130]: ['A']
In [131]: alpha[0:1] = 'a'
In [132]: alpha
Out[132]: ['a', 'b', 'c', 'd', 'e', 'f']
In [133]: alpha[0:2] = ['A', 'B']
In [134]: alpha
Out[134]: ['A', 'B', 'c', 'd', 'e', 'f']
In [135]: alpha[2:2] = ['x', 'xx']
In [136]: alpha
Out[136]: ['A', 'B', 'x', 'xx', 'c', 'd', 'e', 'f']
Adımla Dilimleme:
Şimdiye kadar sürekli kutular seçtiniz. Ancak bazen gizli olarak almanız gerekir. Örneğin, her ikinci kutuyu alabilirsiniz. Hatta her üç kutuyu da sonuna kadar alabilirsiniz. Bu değere adım boyutu denir. Bu birbirini takip eden alıcılarınız arasındaki boşluğu temsil eder. Başından sonuna kadar kutuları seçiyorsanız, adım boyutu pozitif olmalıdır.
In [137]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [142]: alpha[1:5:2]
Out[142]: ['b', 'd']
In [143]: alpha[-1:-5:-2]
Out[143]: ['f', 'd']
In [144]: alpha[1:5:-2]
Out[144]: []
In [145]: alpha[-1:-5:2]
Out[145]: []
Python Eksik Parametreleri Nasıl Anlar:
Dilimleme sırasında, herhangi bir parametreyi dışarıda bırakırsanız, Python otomatik olarak bulmaya çalışır.
CPython'un kaynak kodunu kontrol ederseniz , size herhangi bir parametre için bir dilim endeksleri üzerinden bir işlev çağrıldığında PySlice_GetIndicesEx () rakamları bulacaksınız. İşte Python'daki mantıksal eşdeğer kod.
Bu işlev bir Python nesnesi ve dilimleme için isteğe bağlı parametreleri alır ve istenen dilim için başlangıç, durdurma, adım ve dilim uzunluğunu döndürür.
def py_slice_get_indices_ex(obj, start=None, stop=None, step=None):
length = len(obj)
if step is None:
step = 1
if step == 0:
raise Exception("Step cannot be zero.")
if start is None:
start = 0 if step > 0 else length - 1
else:
if start < 0:
start += length
if start < 0:
start = 0 if step > 0 else -1
if start >= length:
start = length if step > 0 else length - 1
if stop is None:
stop = length if step > 0 else -1
else:
if stop < 0:
stop += length
if stop < 0:
stop = 0 if step > 0 else -1
if stop >= length:
stop = length if step > 0 else length - 1
if (step < 0 and stop >= start) or (step > 0 and start >= stop):
slice_length = 0
elif step < 0:
slice_length = (stop - start + 1)/(step) + 1
else:
slice_length = (stop - start - 1)/(step) + 1
return (start, stop, step, slice_length)
Dilimlerin arkasında bulunan zeka budur. Python, dilim adı verilen yerleşik bir işleve sahip olduğundan, bazı parametreleri iletebilir ve eksik parametreleri ne kadar akıllı hesapladığını kontrol edebilirsiniz.
In [21]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [22]: s = slice(None, None, None)
In [23]: s
Out[23]: slice(None, None, None)
In [24]: s.indices(len(alpha))
Out[24]: (0, 6, 1)
In [25]: range(*s.indices(len(alpha)))
Out[25]: [0, 1, 2, 3, 4, 5]
In [26]: s = slice(None, None, -1)
In [27]: range(*s.indices(len(alpha)))
Out[27]: [5, 4, 3, 2, 1, 0]
In [28]: s = slice(None, 3, -1)
In [29]: range(*s.indices(len(alpha)))
Out[29]: [5, 4]
Not: Bu yazı ilk olarak Python Dlices Behind The Intelligence blogumda yazılmıştır .
Genel bir kural olarak, çok sayıda sabit kodlanmış dizin değeri içeren kod yazmak, okunabilirlik ve bakım karmaşasına yol açar. Örneğin, bir yıl sonra koda geri dönerseniz, koda bakar ve yazarken ne düşündüğünüzü merak edersiniz. Gösterilen çözüm, kodunuzun gerçekte ne yaptığını daha açık bir şekilde belirtmenin bir yoludur. Genel olarak, yerleşik dilim () bir dilime izin verilen her yerde kullanılabilen bir dilim nesnesi oluşturur. Örneğin:
>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4)
>>> items[2:4]
[2, 3]
>>> items[a]
[2, 3]
>>> items[a] = [10,11]
>>> items
[0, 1, 10, 11, 4, 5, 6]
>>> del items[a]
>>> items
[0, 1, 4, 5, 6]
Bir dilim örneğiniz varsa, sırasıyla s.start, s.stop ve s.step özelliklerine bakarak bu konuda daha fazla bilgi edinebilirsiniz. Örneğin:
>>> a = slice(10, 50, 2) >>> a.start 10 >>> a.stop 50 >>> a.step 2 >>>
Basitleştirmek için dilimin sadece bir formu olduğunu unutmayın :
s[start:end:step]
ve işleyiş şekli:
s
: dilimlenebilen bir nesnestart
: yinelemeyi başlatmak için ilk dizinend
: Geçen indeksi, NOT o end
indeks sonuçlandı dilim dahil edilmeyecektirstep
: her step
dizinde öğe seçBaşka ithalat şey: hepsi start
, end
, step
atlanabilir! Onlar atlanmıştır eğer, varsayılan değer kullanılan olacaktır: 0
, len(s)
, 1
buna göre.
Yani olası varyasyonlar:
# Mostly used variations
s[start:end]
s[start:]
s[:end]
# Step-related variations
s[:end:step]
s[start::step]
s[::step]
# Make a copy
s[:]
NOT: start >= end
(Sadece ne zaman dikkate alınırsa step>0
), Python boş bir dilim döndürür []
.
Yukarıdaki bölüm, dilimin nasıl çalıştığına ilişkin temel özellikleri açıklar ve çoğu durumda çalışır. Bununla birlikte, dikkat etmeniz gereken tuzaklar olabilir ve bu bölüm bunları açıklar.
Python öğrenenlerini şaşırtan ilk şey, bir endeksin negatif olabileceğidir! Panik yapmayın: negatif bir dizin geriye doğru sayım anlamına gelir.
Örneğin:
s[-5:] # Start at the 5th index from the end of array,
# thus returning the last 5 elements.
s[:-5] # Start at index 0, and end until the 5th index from end of array,
# thus returning s[0:len(s)-5].
İşleri daha karmaşık hale getirmek step
de olumsuz olabilir!
Negatif bir adım diziyi geriye doğru yinelemek anlamına gelir: uçtan başa, bitiş dizini dahil ve başlangıç dizini sonuçtan hariç tutulur.
NOT : Adım negatif, varsayılan değeri olduğunda start
ise len(s)
(iken end
için eşit olmadığını 0
, çünkü s[::-1]
içerir s[0]
). Örneğin:
s[::-1] # Reversed slice
s[len(s)::-1] # The same as above, reversed slice
s[0:len(s):-1] # Empty list
Sürpriz yapılmış: endeksi aralık dışında olduğunda dilim bir IndexError zam yok!
Dizin aralık dışındaysa, Python dizini duruma göre 0
veya len(s)
duruma göre ayarlamak için elinden geleni yapacaktır . Örneğin:
s[:len(s)+5] # The same as s[:len(s)]
s[-len(s)-5::] # The same as s[0:]
s[len(s)+5::-1] # The same as s[len(s)::-1], and the same as s[::-1]
Bu cevabı, tartıştığımız her şeyi açıklayarak örneklerle bitirelim:
# Create our array for demonstration
In [1]: s = [i for i in range(10)]
In [2]: s
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]: s[2:] # From index 2 to last index
Out[3]: [2, 3, 4, 5, 6, 7, 8, 9]
In [4]: s[:8] # From index 0 up to index 8
Out[4]: [0, 1, 2, 3, 4, 5, 6, 7]
In [5]: s[4:7] # From index 4 (included) up to index 7(excluded)
Out[5]: [4, 5, 6]
In [6]: s[:-2] # Up to second last index (negative index)
Out[6]: [0, 1, 2, 3, 4, 5, 6, 7]
In [7]: s[-2:] # From second last index (negative index)
Out[7]: [8, 9]
In [8]: s[::-1] # From last to first in reverse order (negative step)
Out[8]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
In [9]: s[::-2] # All odd numbers in reversed order
Out[9]: [9, 7, 5, 3, 1]
In [11]: s[-2::-2] # All even numbers in reversed order
Out[11]: [8, 6, 4, 2, 0]
In [12]: s[3:15] # End is out of range, and Python will set it to len(s).
Out[12]: [3, 4, 5, 6, 7, 8, 9]
In [14]: s[5:1] # Start > end; return empty list
Out[14]: []
In [15]: s[11] # Access index 11 (greater than len(s)) will raise an IndexError
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-15-79ffc22473a3> in <module>()
----> 1 s[11]
IndexError: list index out of range
Önceki cevaplar, ünlü NumPy paketini kullanarak mümkün olan çok boyutlu dizi dilimlemeyi tartışmıyor :
Dilimleme çok boyutlu dizilere de uygulanabilir.
# Here, a is a NumPy array
>>> a
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
>>> a[:2, 0:3:2]
array([[1, 3],
[5, 7]])
" :2
" Virgül ilk boyut üzerinde çalışan ve daha önce " 0:3:2
" virgül ikinci boyut çalışır sonra.
list
ancak array
Numpy'de yapamayacağınızı hatırlatan dostça bir hatırlatma
#!/usr/bin/env python
def slicegraphical(s, lista):
if len(s) > 9:
print """Enter a string of maximum 9 characters,
so the printig would looki nice"""
return 0;
# print " ",
print ' '+'+---' * len(s) +'+'
print ' ',
for letter in s:
print '| {}'.format(letter),
print '|'
print " ",; print '+---' * len(s) +'+'
print " ",
for letter in range(len(s) +1):
print '{} '.format(letter),
print ""
for letter in range(-1*(len(s)), 0):
print ' {}'.format(letter),
print ''
print ''
for triada in lista:
if len(triada) == 3:
if triada[0]==None and triada[1] == None and triada[2] == None:
# 000
print s+'[ : : ]' +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] == None and triada[1] == None and triada[2] != None:
# 001
print s+'[ : :{0:2d} ]'.format(triada[2], '','') +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] == None and triada[1] != None and triada[2] == None:
# 010
print s+'[ :{0:2d} : ]'.format(triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] == None and triada[1] != None and triada[2] != None:
# 011
print s+'[ :{0:2d} :{1:2d} ]'.format(triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] == None and triada[2] == None:
# 100
print s+'[{0:2d} : : ]'.format(triada[0]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] == None and triada[2] != None:
# 101
print s+'[{0:2d} : :{1:2d} ]'.format(triada[0], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] != None and triada[2] == None:
# 110
print s+'[{0:2d} :{1:2d} : ]'.format(triada[0], triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] != None and triada[2] != None:
# 111
print s+'[{0:2d} :{1:2d} :{2:2d} ]'.format(triada[0], triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif len(triada) == 2:
if triada[0] == None and triada[1] == None:
# 00
print s+'[ : ] ' + ' = ', s[triada[0]:triada[1]]
elif triada[0] == None and triada[1] != None:
# 01
print s+'[ :{0:2d} ] '.format(triada[1]) + ' = ', s[triada[0]:triada[1]]
elif triada[0] != None and triada[1] == None:
# 10
print s+'[{0:2d} : ] '.format(triada[0]) + ' = ', s[triada[0]:triada[1]]
elif triada[0] != None and triada[1] != None:
# 11
print s+'[{0:2d} :{1:2d} ] '.format(triada[0],triada[1]) + ' = ', s[triada[0]:triada[1]]
elif len(triada) == 1:
print s+'[{0:2d} ] '.format(triada[0]) + ' = ', s[triada[0]]
if __name__ == '__main__':
# Change "s" to what ever string you like, make it 9 characters for
# better representation.
s = 'COMPUTERS'
# add to this list different lists to experement with indexes
# to represent ex. s[::], use s[None, None,None], otherwise you get an error
# for s[2:] use s[2:None]
lista = [[4,7],[2,5,2],[-5,1,-1],[4],[-4,-6,-1], [2,-3,1],[2,-3,-1], [None,None,-1],[-5,None],[-5,0,-1],[-5,None,-1],[-1,1,-2]]
slicegraphical(s, lista)
Bu komut dosyasını çalıştırabilir ve onunla deneme yapabilirsiniz, aşağıda komut dosyasından aldığım bazı örnekler var.
+---+---+---+---+---+---+---+---+---+
| C | O | M | P | U | T | E | R | S |
+---+---+---+---+---+---+---+---+---+
0 1 2 3 4 5 6 7 8 9
-9 -8 -7 -6 -5 -4 -3 -2 -1
COMPUTERS[ 4 : 7 ] = UTE
COMPUTERS[ 2 : 5 : 2 ] = MU
COMPUTERS[-5 : 1 :-1 ] = UPM
COMPUTERS[ 4 ] = U
COMPUTERS[-4 :-6 :-1 ] = TU
COMPUTERS[ 2 :-3 : 1 ] = MPUT
COMPUTERS[ 2 :-3 :-1 ] =
COMPUTERS[ : :-1 ] = SRETUPMOC
COMPUTERS[-5 : ] = UTERS
COMPUTERS[-5 : 0 :-1 ] = UPMO
COMPUTERS[-5 : :-1 ] = UPMOC
COMPUTERS[-1 : 1 :-2 ] = SEUM
[Finished in 0.9s]
Olumsuz bir adım kullanırken, cevabın sağa 1 kaydırıldığına dikkat edin.
-Benim maddeyi lst[start:end]
içeren beynimi kabul etmekten mutluluk start
duyuyor. Hatta bunun 'doğal bir varsayım' olduğunu söyleyebilirim.
Ancak bazen bir şüphe içine girer ve beynim- end
elementi içermediğinden emin olmayı ister.
Bu anlarda bu basit teoreme güveniyorum:
for any n, lst = lst[:n] + lst[n:]
Bu güzel özellik, içinde olduğu lst[start:end]
için end
-th öğesini içermediğini söylüyor lst[end:]
.
Bu teoremin hiç kimse için geçerli olmadığını unutmayın n
. Örneğin,
lst = range(10)
lst[:-42] + lst[-42:] == lst
döner True
.
Bence, Python string dilimleme gösterimini aşağıdaki şekilde bakarsanız daha iyi anlayacak ve ezberleyeceksiniz (okumaya devam edin).
Aşağıdaki dizeyle çalışalım ...
azString = "abcdefghijklmnopqrstuvwxyz"
Bilmeyenler azString
için gösterimi kullanarak herhangi bir alt dize oluşturabilirsinizazString[x:y]
Diğer programlama dillerinden geliyor, o zaman sağduyu tehlikeye giriyor. X ve y nedir?
Oturmak ve x ve y'nin ne olduğunu hatırlamama ve ilk denemede dizeleri düzgün bir şekilde dilimlememe yardımcı olacak bir ezberleme tekniği arayışımda birkaç senaryo çalıştırmak zorunda kaldım.
Sonuç olarak, x ve y, ekstralamak istediğimiz dizeleri çevreleyen sınır indeksleri olarak görülmelidir. Bu yüzden ifadeyi olduğu gibi azString[index1, index2]
veya daha net olarak görmeliyiz azString[index_of_first_character, index_after_the_last_character]
.
İşte bunun bir örnek görselleştirmesi ...
Letters a b c d e f g h i j ...
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
┊ ┊
Indexes 0 1 2 3 4 5 6 7 8 9 ...
┊ ┊
cdefgh index1 index2
Tek yapmanız gereken index1 ve index2'yi istenen alt dizeyi çevreleyecek değerlere ayarlamaktır. Örneğin, "cdefgh" alt dizesini almak için şunu kullanabilirsiniz:azString[2:8]
, çünkü "c" nin sol tarafındaki dizin 2 ve "h" nin sağ boyutundaki dizin 8'dir.
Sınırları belirlediğimizi unutmayın. Ve bu sınırlar, alt dize etrafına sarılacak bazı parantezler yerleştirebileceğiniz konumlardır ...
ab [ cdefgh ] ij
Bu numara her zaman çalışır ve ezberlenmesi kolaydır.
Önceki cevapların çoğu dilim gösterimi ile ilgili soruları siler.
Dilimleme için kullanılan genişletilmiş dizin oluşturma sözdizimi şöyledir aList[start:stop:step]
ve temel örnekler şunlardır:
Diğer dilimleme örnekleri: 15 Genişletilmiş Dilimler
Python'da dilimleme için en temel biçim şudur:
l[start:end]
burada l
bazı koleksiyonlar, start
kapsayıcı bir endekstir ve end
özel bir endekstir.
In [1]: l = list(range(10))
In [2]: l[:5] # First five elements
Out[2]: [0, 1, 2, 3, 4]
In [3]: l[-5:] # Last five elements
Out[3]: [5, 6, 7, 8, 9]
Başlangıçtan dilimleme yaparken, sıfır dizinini atlayabilir ve sonuna kadar dilimleme yaparken, gereksiz olduğu için son dizini atlayabilirsiniz, bu yüzden ayrıntılı olmayın:
In [5]: l[:3] == l[0:3]
Out[5]: True
In [6]: l[7:] == l[7:len(l)]
Out[6]: True
Negatif tamsayılar, bir koleksiyonun sonuna göre ofsetler yaparken yararlıdır:
In [7]: l[:-1] # Include all elements but the last one
Out[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8]
In [8]: l[-3:] # Take the last three elements
Out[8]: [7, 8, 9]
Dilimleme sırasında sınırların dışındaki endeksleri sağlamak mümkündür:
In [9]: l[:20] # 20 is out of index bounds, and l[20] will raise an IndexError exception
Out[9]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [11]: l[-20:] # -20 is out of index bounds, and l[-20] will raise an IndexError exception
Out[11]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Bir koleksiyonu dilimlemenin sonucunun tamamen yeni bir koleksiyon olduğunu unutmayın. Ek olarak, atamalarda dilim gösterimini kullanırken, dilim atamalarının uzunluğunun aynı olması gerekmez. Atanan dilimden önceki ve sonraki değerler tutulur ve koleksiyon yeni değerleri içerecek şekilde küçülür veya büyür:
In [16]: l[2:6] = list('abc') # Assigning fewer elements than the ones contained in the sliced collection l[2:6]
In [17]: l
Out[17]: [0, 1, 'a', 'b', 'c', 6, 7, 8, 9]
In [18]: l[2:5] = list('hello') # Assigning more elements than the ones contained in the sliced collection l [2:5]
In [19]: l
Out[19]: [0, 1, 'h', 'e', 'l', 'l', 'o', 6, 7, 8, 9]
Başlangıç ve bitiş dizinini atlarsanız, koleksiyonun bir kopyasını oluşturacaksınız:
In [14]: l_copy = l[:]
In [15]: l == l_copy and l is not l_copy
Out[15]: True
Bir atama işlemi gerçekleştirilirken başlangıç ve bitiş dizinleri atlanırsa, koleksiyonun tüm içeriği, referans verilenin bir kopyasıyla değiştirilir:
In [20]: l[:] = list('hello...')
In [21]: l
Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.']
Temel dilimlemenin yanı sıra, aşağıdaki gösterimi uygulamak da mümkündür:
l[start:end:step]
burada l
bir koleksiyon, start
kapsayıcı bir indeks, end
özel bir endekstir ve step
her nci öğeyi almak için kullanılabilecek bir adımdırl
.
In [22]: l = list(range(10))
In [23]: l[::2] # Take the elements which indexes are even
Out[23]: [0, 2, 4, 6, 8]
In [24]: l[1::2] # Take the elements which indexes are odd
Out[24]: [1, 3, 5, 7, 9]
Kullanmak step
, Python'daki bir koleksiyonu tersine çevirmek için yararlı bir numara sağlar:
In [25]: l[::-1]
Out[25]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
step
Aşağıdaki örnek için negatif tamsayıların kullanılması da mümkündür :
In[28]: l[::-2]
Out[28]: [9, 7, 5, 3, 1]
Ancak, için negatif bir değer kullanmak step
çok kafa karıştırıcı olabilir. Üstelik olabilmek için Pythonic , sen kullanmaktan kaçınmalısınız start
, end
ve step
tek bir dilim içinde. Bunun gerekli olması durumunda, bunu iki ödevde yapmayı düşünün (biri dilim için diğeri adım için).
In [29]: l = l[::2] # This step is for striding
In [30]: l
Out[30]: [0, 2, 4, 6, 8]
In [31]: l = l[1:-1] # This step is for slicing
In [32]: l
Out[32]: [2, 4, 6]
Bir tane eklemek istiyorum Merhaba, Dünya! yeni başlayanlar için dilimlerin temellerini açıklayan bir örnek. Bana çok yardımcı oldu.
Altı değere sahip bir liste yapalım ['P', 'Y', 'T', 'H', 'O', 'N']
:
+---+---+---+---+---+---+
| P | Y | T | H | O | N |
+---+---+---+---+---+---+
0 1 2 3 4 5
Şimdi bu listenin en basit dilimleri alt listeleridir. Gösterim [<index>:<index>]
ve anahtar onu şöyle okumaktır:
[ start cutting before this index : end cutting before this index ]
Şimdi [2:5]
yukarıdaki listeden bir dilim yaparsanız , bu gerçekleşir:
| |
+---+---|---+---+---|---+
| P | Y | T | H | O | N |
+---+---|---+---+---|---+
0 1 | 2 3 4 | 5
Dizinli öğeden önce bir kesim ve dizinli öğeden önce2
başka bir kesim yaptınız . Sonuç, bu iki kesim arasında bir dilim olacak, bir liste .5
['T', 'H', 'O']
Aşağıda bir dizenin dizini örneği verilmiştir:
+---+---+---+---+---+
| H | e | l | p | A |
+---+---+---+---+---+
0 1 2 3 4 5
-5 -4 -3 -2 -1
str="Name string"
Dilimleme örneği: [başlangıç: bitiş: adım]
str[start:end] # Items start through end-1
str[start:] # Items start through the rest of the array
str[:end] # Items from the beginning through end-1
str[:] # A copy of the whole array
Aşağıda örnek kullanım verilmiştir:
print str[0] = N
print str[0:2] = Na
print str[0:7] = Name st
print str[0:7:2] = Nm t
print str[0:-1:2] = Nm ti
Dilimlemedeki negatif indekslerin kafa karıştırıcı olduğunu düşünüyorsanız, bunu düşünmenin çok kolay bir yolu var: negatif dizini yerine koyun len - index
. Örneğin, -3 ile değiştirin len(list) - 3
.
Dilimlemenin dahili olarak ne yaptığını göstermenin en iyi yolu, onu bu işlemi uygulayan kodda göstermektir:
def slice(list, start = None, end = None, step = 1):
# Take care of missing start/end parameters
start = 0 if start is None else start
end = len(list) if end is None else end
# Take care of negative start/end parameters
start = len(list) + start if start < 0 else start
end = len(list) + end if end < 0 else end
# Now just execute a for-loop with start, end and step
return [list[i] for i in range(start, end, step)]
Temel dilimleme tekniği, başlangıç noktası, durma noktası ve adım boyutunu tanımlamaktır - adım olarak da bilinir.
İlk olarak, dilimlememizde kullanılacak değerlerin bir listesini oluşturacağız.
Dilim için iki liste oluşturun. Birincisi, 1'den 9'a kadar bir sayısal listedir (A Listesi). İkincisi ayrıca 0-9 arasında bir sayısal listedir (Liste B):
A = list(range(1, 10, 1)) # Start, stop, and step
B = list(range(9))
print("This is List A:", A)
print("This is List B:", B)
A'dan 3 sayısını ve B'den 6 sayısını endeksleyin.
print(A[2])
print(B[6])
Temel Dilimleme
Dilimleme için kullanılan genişletilmiş dizin oluşturma sözdizimi aList [start: stop: step] 'dir. Başlangıç bağımsız değişkeni ve adım bağımsız değişkeninin ikisi de varsayılan olarak yok - tek gerekli bağımsız değişken dur. Bunun, A ve B listelerini tanımlamak için aralığın nasıl kullanıldığına benzer olduğunu fark ettiniz mi? Bunun nedeni, dilim nesnesinin aralık (start, stop, step) ile belirtilen dizin kümesini temsil etmesidir. Python 3.4 belgeleri.
Gördüğünüz gibi, yalnızca durağı tanımlamak bir öğe döndürür. Başlangıç varsayılanı yok olarak ayarlandığından, bu yalnızca bir öğenin alınması anlamına gelir.
İlk öğenin dizin 1 değil dizin 0 olduğunu belirtmek önemlidir . Bu nedenle bu alıştırma için 2 liste kullanıyoruz. Liste A'nın elemanları sıralı konuma göre numaralandırılır (ilk öğe 1, ikinci öğe 2 vb.), Liste B'nin öğeleri onları endekslemek için kullanılacak sayılardır (ilk öğe 0 için [0], vb.).
Genişletilmiş dizin oluşturma sözdizimi ile, bir dizi değer alırız. Örneğin, tüm değerler iki nokta üst üste ile alınır.
A[:]
Bir eleman alt kümesini almak için, başlangıç ve bitiş konumlarının tanımlanması gerekir.
AList [start: stop] deseni göz önüne alındığında, ilk iki öğeyi A Listesinden alın.
Python öğretici diyagramının (çeşitli cevaplarda belirtildiği gibi) iyi olduğunu düşünmüyorum, çünkü bu öneri olumlu adım için çalışıyor, ancak olumsuz bir adım için değil.
Bu diyagram:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
Diyagram, ben bekliyoruz a[-4,-6,-1]
olmak yP
ama öyle ty
.
>>> a = "Python"
>>> a[2:4:1] # as expected
'th'
>>> a[-4:-6:-1] # off by 1
'ty'
Her zaman işe yarayan şey, karakterlerde veya yuvalarda düşünmek ve dizine eklemeyi yarı açık bir aralık olarak kullanmaktır - pozitif adım ise sağ açık, negatif adım ise sola açık.
Bu şekilde, aklıma a[-4:-6:-1]
olarak a(-6,-4]
aralık terminolojisinde.
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
+---+---+---+---+---+---+---+---+---+---+---+---+
| P | y | t | h | o | n | P | y | t | h | o | n |
+---+---+---+---+---+---+---+---+---+---+---+---+
-6 -5 -4 -3 -2 -1 0 1 2 3 4 5