Sekanslara abone olurken Python'da :: (çift kolon) nedir?


263

string[3:4]Python'da bir alt dize almak gibi bir şey kullanabileceğimi biliyorum , ama 3 ne anlama geliyor somesequence[::3]?


kimin önce gelmesi ne anlama geliyor :: beğen [5::]. Peki bu 5 ile ne anlama geliyor?
Umar Asghar

1
[5 ::] ilk elementle başlamak, ikincisi için hiçbir şey ifade
etmemek

Yanıtlar:


243

'ilk argüman için hiçbir şey, ikincisi için hiçbir şey ve üçe zıplama' anlamına gelir. Dizinin her üç maddesini dilimlenir. Genişletilmiş dilimler istediğiniz şeydir. Python 2.3'teki yenilikler


99
Ayrıca, bir listeyi ters çevirmek için de kullanılabilir [:: - 1]
thavan

22
Her öğeyi 3'ün katı olan bir konuma döndürür . 3 * 0 = 0 olduğundan, 0 konumundaki öğeyi de döndürür. Örneğin: range(10)[::3]çıkışlar[0, 3, 6, 9]
Ricky Robinson

1
daha önce kimin gelmesi ne anlama geliyor ::[n ::]. Peki bunun anlamı ne n?
Umar Asghar

154

Python sekans dilim adresleri bir [start: end: step] olarak yazılabilir ve start, stop veya end herhangi biri bırakılabilir. a[::3]dizinin her üçüncü elemanıdır.


85

seq[::n]"Sekans", nsekansın tamamındaki her bir öğenin sekansıdır.

Misal:

>>> range(10)[::2]
[0, 2, 4, 6, 8]

Sözdizimi:

seq[start:end:step]

Böylece şunları yapabilirsiniz:

>>> range(100)[5:18:2]
[5, 7, 9, 11, 13, 15, 17]

4
Python 3'te, örnek aralığınız (N) [:: adım] bir liste değil bir aralık nesnesi üretir. Gerçekten neler olduğunu görmek için, aralığı bir listeye zorlamanız gerekir, np.array, vb.
PikalaxALT

57

açıklama

s[i:j:k]olduğu belgelere göre , "aşama k j i S dilim". iVe jolmadığı zaman , tüm dizi varsayılır ve dolayısıyla s[::k]"her k-inci madde" anlamına gelir.

Örnekler

İlk olarak, bir liste başlatalım:

>>> s = range(20)
>>> s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Her 3. öğeyi aşağıdakilerden alalım s:

>>> s[::3]
[0, 3, 6, 9, 12, 15, 18]

Her 3. öğeyi aşağıdakilerden alalım s[2:]:

>>> s[2:]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> s[2::3]
[2, 5, 8, 11, 14, 17]

Her 3. öğeyi aşağıdakilerden alalım s[5:12]:

>>> s[5:12]
[5, 6, 7, 8, 9, 10, 11]
>>> s[5:12:3]
[5, 8, 11]

Her 3. öğeyi aşağıdakilerden alalım s[:10]:

>>> s[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> s[:10:3]
[0, 3, 6, 9]

inanılmaz cevap!
Jürgen K.

30

TL; DR

Bu görsel örnek, bir NumPy Matrisindeki (2 boyutlu dizi) öğeleri oldukça eğlenceli bir şekilde nasıl seçeceğinizi gösterecektir (söz veriyorum). Aşağıdaki 2. Adım, söz konusu "çift kolonların" kullanımını göstermektedir ::.

(Dikkat: Bu, ::öğelerin birden çok eksende atlanması için bir "çift kolon" kullanım örneğini göstermek amacıyla NumPy dizisine özgü bir örnektir . Bu örnek, yerel Python veri yapılarını kapsamaz List).

Hepsine hükmedecek somut bir örnek ...

Diyelim ki şuna benzer bir NumPy matrisi var:

In [1]: import numpy as np

In [2]: X = np.arange(100).reshape(10,10)

In [3]: X
Out[3]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
       [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
       [70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
       [80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
       [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])

Bir sebepten ötürü, patronunuz aşağıdaki öğeleri seçmenizi istiyor:

resim açıklamasını buraya girin

“Ama Nasıl ???” ... Okumaya devam et! (Bunu 2 adımlı bir yaklaşımla yapabiliriz)

Adım 1 - Alt kümeyi edinin

Hem satır hem de sütun yönlerinde "başlangıç ​​dizini" ve "bitiş dizini" ni belirtin.

resim açıklamasını buraya girin

Kodda:

In [5]: X2 = X[2:9,3:8]

In [6]: X2
Out[6]:
array([[23, 24, 25, 26, 27],
       [33, 34, 35, 36, 37],
       [43, 44, 45, 46, 47],
       [53, 54, 55, 56, 57],
       [63, 64, 65, 66, 67],
       [73, 74, 75, 76, 77],
       [83, 84, 85, 86, 87]])

Şimdi basit başlangıç ​​ve bitiş indeksleme tekniği ile alt kümemizi aldık. Sıradaki, bu "zıplama" nasıl yapılır ... (okumaya devam edin!)

2. Adım - Öğeleri seçin ("atlama adımı" bağımsız değişkeniyle)

Artık "atlama adımlarını" hem satır hem de sütun yönlerinde ("atlama" yolundaki öğeleri seçmek için) şu şekilde belirtebiliriz:

resim açıklamasını buraya girin

Kodda (çift sütunlara dikkat edin):

In [7]: X3 = X2[::3, ::2]

In [8]: X3
Out[8]:
array([[23, 25, 27],
       [53, 55, 57],
       [83, 85, 87]])

Tüm elemanları gerektiği gibi seçtik! :)

 Adım 1'i (başlangıç ​​ve bitiş) ve Adım 2'yi ("atlama") birleştirin

Şimdi kavramı biliyoruz, adım 1 ve adım 2'yi tek bir birleştirilmiş adımda kolayca birleştirebiliriz - kompaktlık için:

In [9]: X4 = X[2:9,3:8][::3,::2]

    In [10]: X4
    Out[10]:
    array([[23, 25, 27],
           [53, 55, 57],
           [83, 85, 87]])

Bitti!


İşaretli girişlerin her birini orijinal nesnede 0 olarak ayarlamak istersem ne olur? Nasıl devam edilir?
user1211030

1
Bir X[2:9,3:8][::3,::2] = 0 (işaretli girişleri 0 olarak değiştirmek için) yapın. Eğer yazarsanız Xyine tüm bu işaretli girişleri artık ayarlanır göreceğiz 0.
Atlas7

15

Python'da dilimleme yaparken üçüncü parametre adımdır. Diğerlerinin de belirttiği gibi, güzel bir genel bakış için Genişletilmiş Dilimler'e bakın .

Bu bilgi ile, [::3]diliminiz için herhangi bir başlangıç ​​veya bitiş endeksi belirtmediğiniz anlamına gelir. Bir adım belirttiğiniz için 3, bu işlem somethingilk dizinden başlamanın her üçüncü girişini alacaktır . Örneğin:

>>> '123123123'[::3]
'111'

7

Bu gösterimi istediğiniz gibi yapmak için kendi özel sınıflarınızda da kullanabilirsiniz

class C(object):
    def __getitem__(self, k):
        return k

# Single argument is passed directly.
assert C()[0] == 0

# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)

# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)

# If you omit any part of the slice notation, it becomes None.
assert C()[:] == slice(None, None, None)
assert C()[::] == slice(None, None, None)
assert C()[1::] == slice(1, None, None)
assert C()[:2:] == slice(None, 2, None)
assert C()[::3] == slice(None, None, 3)

# Tuple with a slice object:
assert C()[:, 1] == (slice(None, None, None), 1)

# Ellipsis class object.
assert C()[...] == Ellipsis

Daha sonra dilim nesnelerini şu şekilde açabiliriz:

s = slice(1, 2, 3)
assert s.start == 1
assert s.stop == 2
assert s.step == 3

Bu özellikle Numpy'de çok boyutlu dizileri herhangi bir yönde dilimlemek için kullanılır.

Tabii ki, herhangi bir aklı başında API ::3her zamanki "her 3" semantik ile kullanmalıdır.

Bununla ilgili Ellipsisdaha fazla bilgi: Üç nokta nesnesi ne yapar?


6

Üçüncü parametre adımdır. Böylece [:: 3] listenin / dizenin her 3 elemanını döndürür.


4

Python :: ile End, Start ve Step değerlerini birbirinden ayırır.


1
Bu gerçekten yardımcı olmak için yeterli ayrıntı sağlamaz.
bstpierre

4
"Başlangıç, Bitiş ve Adım" demek istemiyor musunuz? Bunları sıra dışı listelemek yanıltıcı görünüyor.
Jon Coombs
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.