Dilim gösterimini anlama


3283

Python'ın dilim gösterimi üzerinde iyi bir açıklama (referanslar bir artı) gerekir.

Bana göre, bu gösterimin biraz kaldırılması gerekiyor.

Son derece güçlü görünüyor, ama kafamı tam olarak bulamadım.

Yanıtlar:


4501

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

stepYukarı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, :stopdeğerin seçilen dilimde olmayan ilk değeri temsil etmesidir. Bu nedenle, arasındaki fark stopve start(eğer seçilen elemanlarının sayısı step1, varsayılan).

Diğer bir özellik olduğunu startveya stopbir 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, stepnegatif 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 ahata 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şki

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


122
Yerleşik türlerin dilimlenmesi bir kopya döndürür, ancak bu evrensel değildir. Özellikle, NumPy dizilerini dilimlemek , belleği orijinal ile paylaşan bir görünüm döndürür.
Beni Cherniavsky-Paskin

43
Bu, kanıtlamak için oylarla güzel bir cevaptır, ancak bir şeyi kaçırır: Noneboş 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.
Mark Ransom

6
Beni gerçekten sinirlendiren şey, python'un başlangıç ​​ve bitişi ayarlamadığınızda, varsayılan olarak 0'a ve sıra uzunluğuna sahip olduğunu söylüyor. Bu nedenle, teoride, "abcdef" [:: - 1] kullandığınızda "abcdef" [0: 6: -1] biçimine dönüştürülmelidir, ancak bu iki ifade aynı çıktıyı almaz. Dilin oluşturulmasından bu yana python belgelerinde bir şeylerin eksik olduğunu hissediyorum.
axell13

6
[:: - 1] Ve "abcdef'ait" biliyoruz "abcdef'ait" [6: 7: -1] dönüştürülür, yani, açıklamak için en iyi şekilde olacaktır: izin uzunluk dizisinin uzunluğu. Adım pozitifse , başlangıç ​​ve bitiş varsayılanları 0 ve len'dir . Basamak negatifse , başlangıç ​​ve bitiş varsayılanları len ve - len - 1'dir.
axell13

4
Yana stackoverflow.com/questions/39241529/... Bunun dupe işaretlenir, bu anlamda ne bir bölüm eklemek için yapacak delwrt 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.)
khazhyk

538

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 .


10
Bu öneri olumlu adım için geçerlidir, ancak olumsuz adım için geçerli değildir. Diyagram, ben bekliyoruz a[-4,-6,-1]olmak yPama ö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.
aguadopd

Ancak boş bir sete sondan başlayarak daralmanın yolu yoktur ( x[:0]en baştan başlarken olduğu gibi ), bu nedenle özel durumdaki küçük dizileri kullanmanız gerekir. : /
endolit

412

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 stridenegatifse, 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)'

Aslında hala bir şey kaldı, örneğin 'elma' yazarsam [4: -4: -1] 'elp' alırım, python -4'ü 1'e çeviriyor olabilir mi?
liyuan

backticks lehine repr
onaylandığını

@liyuan Tip uygulama __getitem__; örneğiniz buna eşdeğerdir apple[slice(4, -4, -1)].
Chepner

320

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.


246

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

Önemli Tanımlar

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.

Dizin Oluşturma Nasıl Çalışır?

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

Dilimleme Nasıl Çalışır

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)

Açıklama:

Tam gösterim

my_list[-9:None:None]

ve varsayılanları değiştirmek için (aslında stepnegatif olduğunda , stopvarsayılanı varsayılan -len(my_list) - 1, bu yüzden Nonedurmak 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.copyve list.clearyöntemi alır .)

Ne zaman stepnegatif için varsayılan olduğunu startve stopdeğişim

Varsayılan olarak, stepbağı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 startve stop!

Bunu kaynakta onaylama

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 stepnegatif 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 -1olan farklı bir gelen -1kullanı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 steppozitiftir 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, startve için varsayılan değerleri uygulamamız gerekebilir stop- - negatif startise , 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 stopalt sınır:

if (self->stop == Py_None) {
    stop = step_is_negative ? lower : upper;
    Py_INCREF(stop);
}

Dilimlerinize açıklayıcı bir ad verin!

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, Noneilk değişken olarak yorumlanır, böylece, gerekli olan startdeğişken , aksi olurdu stopargü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)

Bellek Konuları:

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. islicebunun için mükemmel. Bir yetersizlik, bu olumsuz argümanlar desteklemez start, stopveya 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.


146

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]

100

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]

2
ilginç bir örnek daha: a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]; a[:-2:-2]Hangisi[9]
Deviacium

96

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)

65

Biraz kullandıktan sonra en basit açıklamanın bir fordö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 ...


52

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 stepulaş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 NoneAyrıntılar için endişelenmeyin - unutmayın, startve / veya stopher 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.


3
this_is_how_slicing_worksPiton 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.
Eastsun

@Eastsun Hata! Haklısın! Daha net bir vaka: 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).
Beni Cherniavsky-Paskin

40

"Öğ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.


40
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


38

Python dilimleme notasyonu:

a[start:end:step]
  • İçin startve endnegatif değerler dizisinin sonuna göre olarak yorumlanır.
  • İçin olumlu endeksler end dahil edilecek son elemandan sonraki pozisyonu belirtir .
  • Boş değerler varsayılan olarak aşağıdaki gibidir: [+0:-0:1] .
  • Olumsuz bir adım kullanmak, yorumunu tersine çevirir 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().


34

Listeden bir veya daha fazla öğeyi kaldırmak için dilim atamasını da kullanabilirsiniz:

r = [1, 'blah', 9, 8, 2, 3, 4]
>>> r[1:4] = []
>>> r
[1, 2, 3, 4]

33

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]

33

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.

Resim açıklamasını buraya girin

İç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 .


29

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

25

1. Dilim Gösterimi

Basitleştirmek için dilimin sadece bir formu olduğunu unutmayın

s[start:end:step]

ve işleyiş şekli:

  • s: dilimlenebilen bir nesne
  • start: yinelemeyi başlatmak için ilk dizin
  • end: Geçen indeksi, NOT o endindeks sonuçlandı dilim dahil edilmeyecektir
  • step: her stepdizinde öğe seç

Başka ithalat şey: hepsi start, end, stepatlanabilir! Onlar atlanmıştır eğer, varsayılan değer kullanılan olacaktır: 0, len(s), 1buna 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 [].

2. Tuzaklar

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.

Negatif dizinler

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

Olumsuz adım

İşleri daha karmaşık hale getirmek stepde 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 startise len(s)(iken endiç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

Aralık dışı hatası?

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 0veya 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]

3. Örnekler

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

24

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


4
Bunu Python'da yapamayacağınızı listancak arrayNumpy'de yapamayacağınızı hatırlatan dostça bir hatırlatma
Mars Lee

15
#!/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.


14

-Benim maddeyi lst[start:end]içeren beynimi kabul etmekten mutluluk startduyuyor. Hatta bunun 'doğal bir varsayım' olduğunu söyleyebilirim.

Ancak bazen bir şüphe içine girer ve beynim- endelementi 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.


12

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 azStringiç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.


11

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

Resim açıklamasını buraya girin:

Diğer dilimleme örnekleri: 15 Genişletilmiş Dilimler


10

Python'da dilimleme için en temel biçim şudur:

l[start:end]

burada lbazı koleksiyonlar, startkapsayı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 lbir koleksiyon, startkapsayıcı bir indeks, endözel bir endekstir ve stepher 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]

stepAş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, endve steptek 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]

10

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


10

Şahsen bunu bir fordöngü gibi düşünüyorum :

a[start:end:step]
# for(i = start; i < end; i += step)

Ayrıca, startve için negatif değerlerin endlistenin sonuna göründüğünü ve yukarıdaki örnekte tarafından hesaplandığını unutmayın given_index + a.shape[0].


8

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

5

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

4

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.


3

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 yPama ö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  
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.