Apa itu :: (titik dua) dalam Python saat berlangganan urutan?

264

Saya tahu bahwa saya bisa menggunakan sesuatu seperti string[3:4]untuk mendapatkan substring dengan Python, tetapi apa artinya 3 somesequence[::3]?

Aillyn
sumber
apa artinya yang datang sebelum :: suka [5::]. Jadi apa artinya dengan 5?
Umar Asghar
1
[5 ::] akan berarti mulai dengan elemen pertama, tidak ada untuk yang kedua dan pilih elemen berikutnya
Gagan

Jawaban:

243

itu berarti 'tidak ada untuk argumen pertama, tidak ada untuk argumen kedua, dan melompat tiga'. Itu mendapat setiap item ketiga dari urutan diiris. Irisan diperpanjang adalah yang Anda inginkan. Baru dalam Python 2.3

Adriano Varoli Piazza
sumber
99
Itu juga dapat digunakan untuk membalik daftar menggunakan [:: - 1]
thavan
22
Ini mengembalikan setiap item pada posisi yang merupakan kelipatan dari 3 . Karena 3 * 0 = 0, ia juga mengembalikan item pada posisi 0. Misalnya: range(10)[::3]output[0, 3, 6, 9]
Ricky Robinson
1
apa artinya siapa yang datang sebelumnya ::seperti [n ::]. Jadi apa maksudnya n?
Umar Asghar
154

Alamat irisan urutan python dapat ditulis sebagai [mulai: akhir: langkah] dan mulai, berhenti atau berakhir dapat dijatuhkan. a[::3]adalah setiap elemen ketiga dari urutan.

Deinst
sumber
85

seq[::n]adalah urutan setiap nitem-ke-3 di seluruh urutan.

Contoh:

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

Sintaksnya adalah:

seq[start:end:step]

Jadi kamu bisa melakukan:

>>> range(100)[5:18:2]
[5, 7, 9, 11, 13, 15, 17]
Yuval Adam
sumber
4
Dalam Python 3, rentang contoh Anda (N) [:: langkah] menghasilkan objek rentang, bukan daftar. Untuk benar-benar melihat apa yang terjadi, Anda perlu memaksa rentang ke daftar, np.array, dll.
PikalaxALT
57

Penjelasan

s[i:j:k]adalah, menurut dokumentasi , "irisan s dari i ke j dengan langkah k". Ketika idan jtidak ada, seluruh urutan diasumsikan dan dengan demikian s[::k]berarti "setiap item ke-k".

Contohnya

Pertama, mari kita inisialisasi daftar:

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

Mari kita setiap 3 rd item dari s:

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

Mari kita setiap 3 rd item dari 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]

Mari kita setiap 3 rd item dari s[5:12]:

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

Mari kita setiap 3 rd item dari s[:10]:

>>> s[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> s[:10:3]
[0, 3, 6, 9]
Bolo
sumber
jawaban yang luar biasa!
Jürgen K.
30

TL; DR

Contoh visual ini akan menunjukkan kepada Anda bagaimana memilih elemen dengan rapi dalam Matriks NumPy (array 2 dimensi) dengan cara yang cukup menghibur (saya janji). Langkah 2 di bawah menggambarkan penggunaan "titik dua" ::tersebut.

(Perhatian: ini adalah contoh spesifik array NumPy dengan tujuan mengilustrasikan kasus penggunaan "titik dua" ::untuk melompati elemen dalam banyak sumbu. Contoh ini tidak mencakup struktur data Python asli seperti List).

Salah satu contoh nyata untuk mengatur semuanya ...

Katakanlah kita memiliki matriks NumPy yang terlihat seperti ini:

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

Katakan karena suatu alasan, atasan Anda ingin Anda memilih elemen-elemen berikut:

masukkan deskripsi gambar di sini

"Tapi Bagaimana ???" ... Baca terus! (Kita bisa melakukan ini dalam pendekatan 2 langkah)

Langkah 1 - Dapatkan subset

Tentukan "indeks awal" dan "indeks akhir" dalam arah baris-bijaksana dan kolom-bijaksana.

masukkan deskripsi gambar di sini

Dalam kode:

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

Perhatikan sekarang kami baru saja memperoleh bagian kami, dengan menggunakan teknik pengindeksan awal dan akhir yang sederhana. Selanjutnya, bagaimana melakukan itu "melompat" ... (baca terus!)

Langkah 2 - Pilih elemen (dengan argumen "lompat langkah")

Kita sekarang dapat menentukan "langkah lompatan" di kedua arah baris-bijaksana dan kolom-bijaksana (untuk memilih elemen dalam cara "melompat") seperti ini:

masukkan deskripsi gambar di sini

Dalam kode (perhatikan titik dua):

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

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

Kami baru saja memilih semua elemen sesuai kebutuhan! :)

 Konsolidasi Langkah 1 (mulai dan akhir) dan Langkah 2 ("melompat")

Sekarang kita tahu konsepnya, kita dapat dengan mudah menggabungkan langkah 1 dan langkah 2 menjadi satu langkah konsolidasi - untuk kekompakan:

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

Selesai!

Atlas7
sumber
Bagaimana jika saya ingin mengatur masing-masing entri yang ditandai ke 0 di objek asli? Bagaimana untuk melanjutkan?
user1211030
1
Lakukan a X[2:9,3:8][::3,::2] = 0 (untuk mengganti entri yang ditandai ke 0). Jika Anda mengetik Xlagi, Anda akan melihat semua entri yang ditandai sekarang disetel ke 0.
Atlas7
15

Saat mengiris Python, parameter ketiga adalah langkahnya. Seperti yang disebutkan orang lain, lihat Irisan Diperpanjang untuk tinjauan umum yang bagus.

Dengan pengetahuan ini, [::3]berarti Anda belum menentukan indeks awal atau akhir untuk slice Anda. Karena Anda telah menentukan langkah,, 3ini akan mengambil setiap entri ketiga somethingmulai dari indeks pertama. Sebagai contoh:

>>> '123123123'[::3]
'111'
Justin Ethier
sumber
7

Anda juga dapat menggunakan notasi ini di kelas kustom Anda sendiri untuk membuatnya melakukan apa pun yang Anda inginkan

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

Kami kemudian dapat membuka objek slice sebagai:

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

Ini terutama digunakan dalam Numpy untuk memotong array multi-dimensi ke segala arah.

Tentu saja, setiap API waras harus digunakan ::3dengan semantik "setiap 3" yang biasa.

Yang terkait Ellipsisdibahas lebih lanjut di: Apa yang dilakukan objek Ellipsis?

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
6

Parameter ketiga adalah langkahnya. Jadi [:: 3] akan mengembalikan setiap elemen ke-3 dari daftar / string.

mshafrir
sumber
4

Python menggunakan :: untuk memisahkan nilai Akhir, Mulai, dan Langkah.

POWERRANGERDUDEONCAPS
sumber
1
Ini tidak memberikan detail yang cukup untuk benar-benar bermanfaat.
bstpierre
4
Bukankah maksud Anda "Awal, Akhir, dan Langkah"? Tampaknya menyesatkan untuk mencantumkannya secara salah.
Jon Coombs