Dizin aralık dışı ile alt dize dilimleme neden çalışıyor?


90

Neden 'example'[999:9999]hatayla sonuçlanmıyor? Yana 'example'[9]yapar bunun arkasında motivasyon nedir?

Bu davranıştan , her ikisi de aynı dizeyle sonuçlansa bile 'example'[3], esasen / dahili olarak bunun aynı olmadığını varsayabilirim .'example'[3:4]'m'


17
[999:9999]bir dizin değil, bir dilim ve farklı anlamlara sahip. Python girişinden: "Dilim indeksleri incelikle ele alınır: çok büyük bir indeks, dize boyutuyla değiştirilir, alt sınırdan daha küçük bir üst sınır boş bir dize döndürür."
Wooble

2
@Wooble gerçek cevap
jondavidjohn

2
@ Wooble Ve bunun neden böyle olduğunu biliyor musunuz? Açıklık getirdiğiniz için teşekkürler.
ijverig

Neden? Guido'ya sormanız gerekirdi, ama bir dilimin her zaman orijinal sekansla aynı türde bir sekans olduğunu varsayabilmenin zarif olduğunu düşünüyorum.
Wooble

1
@Lapinot evet bu davranışa bağlı bir kod yazdım. Maalesef tam kodu hatırlayamadığım için nedenini size söyleyemem. Muhtemelen alt dizelerle ilgisi vardı; boş bir dize almak bazen tam olarak istediğiniz şey olabilir.
Mark Ransom

Yanıtlar:


69

Haklısın! 'example'[3:4]ve 'example'[3]temelde farklıdır ve bir dizinin sınırları dışında dilimleme (en azından yerleşik öğeler için) bir hataya neden olmaz.

İlk başta şaşırtıcı gelebilir ama düşündüğünüzde mantıklı geliyor. İndeksleme, tek bir öğeyi döndürür, ancak dilimleme, bir öğe alt dizisini döndürür. Dolayısıyla, var olmayan bir değeri dizine eklemeye çalıştığınızda, döndürülecek bir şey yoktur. Ancak bir diziyi sınırların dışında dilimlediğinizde, yine de boş bir dizi döndürebilirsiniz.

Burada kafa karıştıran şey, dizelerin listelerden biraz farklı davranmasıdır. Bir listeye aynı şeyi yaptığınızda ne olduğuna bakın:

>>> [0, 1, 2, 3, 4, 5][3]
3
>>> [0, 1, 2, 3, 4, 5][3:4]
[3]

Burada fark açıktır. Dizeler söz konusu olduğunda, sonuçlar aynı görünür, çünkü Python'da bir dizenin dışında tek bir karakter diye bir şey yoktur. Tek bir karakter yalnızca 1 karakterlik bir dizedir.

(Bir dizinin aralığının dışında dilimlemenin kesin anlamı için, mgilson'ın cevabına bakın .)


1
Aralık dışı bir dizin None, hata yapmak yerine geri dönebilirdi - bu , geri dönecek bir şeyiniz olmadığında olağan Python kuralıdır.
Mark Ransom

8
@MarkRansom, bu doğru; ancak Nonebu durumda geri dönmek , sınır dışı indeks ile Noneliste içindeki bir değer arasında ayrım yapmayı zorlaştırır . Ancak bunun için bir geçici çözüm olsa bile, sınır dışı bir dilim verildiğinde boş bir diziyi geri döndürmenin yapılacak doğru şey olduğu bana açık kalıyor. İki ayrık kümenin birleşimini gerçekleştirmeye benzer.
senderle

Açık olmak gerekirse, yanıldığını söylemedim. NoneDeğerler hakkındaki düşüncenizi bir listede görüyorum .
Mark Ransom

1
@MarkRansom, biliyorum - savunma amaçlı göründüysem özür dilerim. Gerçekten sadece set teorisine atıfta bulunmak için bir bahane istedim :).
senderle

4
"Kavşak" yerine "birlik" demem dışında.
2014

33

Dokümantasyonda sağlam bir bölüme işaret eden bir cevap eklemek adına :

Gibi bir dilim ifadesi verildiğinde s[i:j:k],

Dilim s gelen i için j aşaması ile k endeksi ile öğeler dizisi olarak tanımlanır x = i + n*k, öyle ki 0 <= n < (j-i)/k. Başka bir deyişle, endeksler vardır i, i+k, i+2*k, i+3*kne zaman ve benzerleri, durdurma j ulaşıldığında (ama asla dahil j ). Ne zaman k pozitiftir, i ve j indirgenir len(s)onlar büyükse

yazarsanız s[999:9999], python o s[len(s):len(s)]zamandan beri geri dönüyor len(s) < 999ve adımınız pozitiftir ( 1- varsayılan).


Muhtemelen ne zaman kolumludur ive daha az olduklarında jda artar -len(s)mı? örneğins = 'bac'; s[-100:2] == s[-len(s):2]
Chris_Rands

@Chris_Rands kPozitif olduğunda, Python ölçeklenir ive jböylece dizinin sınırlarına uyur . Örneğinizde, s[-100:2] == s[0:2]( == s[-len(s):2]bu arada). Benzer şekilde s[-100:100] == s[0:2].
tylerc0816

Güzel, teşekkürler. Bu, @ speedplane'in yukarıdaki yorumuna daha iyi bir yanıttır.
2018

8

Dilimleme, yerleşik türler tarafından sınır kontrolüne tabi değildir. Ve her iki örneğiniz de aynı sonucu veriyor gibi görünse de, farklı çalışıyorlar; bunun yerine bir liste ile deneyin.

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.