Jawaban:
Ini benar-benar sangat sederhana:
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
Ada juga step
nilainya, yang dapat digunakan dengan salah satu di atas:
a[start:stop:step] # start through not past stop, by step
Poin utama yang perlu diingat adalah bahwa :stop
nilai tersebut mewakili nilai pertama yang tidak ada dalam slice yang dipilih. Jadi, perbedaan antara stop
dan start
jumlah elemen yang dipilih (jikastep
1, default).
Fitur lainnya adalah angka itu start
atau stop
mungkin angka negatif , yang artinya dihitung dari akhir array bukan dari awal. Begitu:
a[-1] # last item in the array
a[-2:] # last two items in the array
a[:-2] # everything except the last two items
Demikian pula, step
mungkin angka negatif:
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
Python baik kepada programmer jika ada item lebih sedikit dari yang Anda minta. Misalnya, jika Anda meminta a[:-2]
dan a
hanya berisi satu elemen, Anda mendapatkan daftar kosong dan bukan kesalahan. Terkadang Anda lebih suka kesalahan, jadi Anda harus sadar bahwa ini mungkin terjadi.
slice()
objekOperator slicing []
sebenarnya digunakan dalam kode di atas dengan slice()
objek menggunakan :
notasi (yang hanya valid di dalam []
), yaitu:
a[start:stop:step]
setara dengan:
a[slice(start, stop, step)]
Objek slice juga berperilaku sedikit berbeda tergantung pada jumlah argumen, mirip dengan range()
, yaitu keduanya slice(stop)
dan slice(start, stop[, step])
didukung. Untuk melewati menentukan argumen yang diberikan, orang mungkin menggunakan None
, sehingga misalnya a[start:]
setara dengan a[slice(start, None)]
atau a[::-1]
setara dengan a[slice(None, None, -1)]
.
Sementara :
notasi berbasis-sangat membantu untuk mengiris sederhana, penggunaan eksplisit slice()
objek menyederhanakan generasi pemrograman pemotongan.
None
ruang kosong mana pun. Misalnya [None:None]
membuat salinan lengkap. Ini berguna ketika Anda perlu menentukan akhir rentang menggunakan variabel dan perlu memasukkan item terakhir.
del
notasi irisan slt. Secara khusus, del arr[:]
tidak segera jelas ("arr [:] membuat salinan, begitu juga menghapus del salinan itu ???" dll.)
The Python tutorial berbicara tentang hal itu (scroll ke bawah sedikit sampai Anda mendapatkan ke bagian tentang mengiris).
Diagram seni ASCII juga membantu untuk mengingat cara kerja irisan:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
Salah satu cara untuk mengingat bagaimana irisan bekerja adalah dengan memikirkan indeks sebagai menunjuk di antara karakter, dengan tepi kiri karakter pertama bernomor 0. Kemudian tepi kanan karakter terakhir dari string n karakter memiliki indeks n .
a[-4,-6,-1]
untuk menjadi yP
tetapi ty
. Yang selalu berhasil adalah berpikir dalam karakter atau slot dan menggunakan pengindeksan sebagai interval setengah terbuka - kanan-terbuka jika langkah positif, kiri-terbuka jika langkah negatif.
x[:0]
halnya ketika mulai dari awal), jadi Anda harus array kasus kecil khusus. : /
Menghitung kemungkinan yang diizinkan oleh tata bahasa:
>>> 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]]
Tentu saja, jika (high-low)%stride != 0
, maka titik akhirnya akan sedikit lebih rendah darihigh-1
.
Jika stride
negatif, pemesanan berubah sedikit karena kami menghitung mundur:
>>> 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]]
Pengiris yang diperluas (dengan koma dan elips) sebagian besar hanya digunakan oleh struktur data khusus (seperti NumPy); urutan dasar tidak mendukungnya.
>>> 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__
adalah; contoh Anda setara dengan apple[slice(4, -4, -1)]
.
Jawaban di atas tidak membahas penugasan slice. Untuk memahami penugasan slice, sebaiknya tambahkan konsep lain pada seni ASCII:
+---+---+---+---+---+---+
| 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']
Satu heuristik adalah, untuk irisan dari nol ke n, pikirkan: "nol adalah awal, mulailah dari awal dan ambil n item dalam daftar".
>>> 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']
Heuristik lain adalah, "untuk setiap irisan, ganti start dengan nol, terapkan heuristik sebelumnya untuk mendapatkan akhir daftar, lalu hitung angka pertama kembali untuk memotong item dari awal"
>>> 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.
Aturan pertama penugasan slice adalah bahwa sejak slicing mengembalikan daftar, penugasan slice membutuhkan daftar (atau yang dapat diubah lainnya):
>>> 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
Aturan kedua penugasan slice, yang juga bisa Anda lihat di atas, adalah bahwa bagian apa pun dari daftar dikembalikan oleh pengindeksan slice, itu adalah bagian yang sama yang diubah oleh penugasan slice:
>>> p[2:4]
['T','h']
>>> p[2:4] = ['t','r']
>>> p
['P','y','t','r','o','n']
Aturan penugasan slice yang ketiga adalah, daftar yang ditugaskan (iterable) tidak harus memiliki panjang yang sama; irisan diindeks hanya diiris dan diganti secara massal oleh apa pun yang ditugaskan:
>>> 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']
Bagian tersulit yang digunakan adalah penugasan irisan kosong. Dengan menggunakan heuristik 1 dan 2, Anda dapat dengan mudah mengindeks potongan kosong:
>>> 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]
[]
Dan setelah Anda melihat itu, penugasan slice ke slice kosong juga masuk akal:
>>> 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
Perhatikan bahwa, karena kita tidak mengubah angka kedua dari slice (4), item yang dimasukkan selalu menumpuk tepat di atas 'o', bahkan ketika kita sedang menetapkan slice kosong. Jadi posisi untuk tugas irisan kosong adalah perpanjangan logis dari posisi untuk tugas irisan irisan kosong.
Membackup sedikit, apa yang terjadi ketika Anda terus dengan prosesi kami menghitung awal irisan?
>>> 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]
[]
Dengan mengiris, setelah selesai, Anda selesai; itu tidak mulai mengiris ke belakang. Dalam Python Anda tidak mendapatkan langkah negatif kecuali jika Anda secara eksplisit meminta mereka dengan menggunakan angka negatif.
>>> p[5:3:-1]
['n','o']
Ada beberapa konsekuensi aneh terhadap aturan "setelah selesai, selesai":
>>> 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
Bahkan, dibandingkan dengan pengindeksan, pengiris Python adalah kesalahan-bukti yang aneh:
>>> p[100:200]
[]
>>> p[int(2e99):int(1e99)]
[]
Terkadang hal ini berguna, tetapi juga dapat menyebabkan perilaku yang agak aneh:
>>> 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']
Tergantung pada aplikasi Anda, itu mungkin ... atau mungkin tidak ... menjadi apa yang Anda harapkan di sana!
Di bawah ini adalah teks dari jawaban asli saya. Ini bermanfaat bagi banyak orang, jadi saya tidak ingin menghapusnya.
>>> 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]
Ini juga dapat memperjelas perbedaan antara pengirisan dan pengindeksan.
Jelaskan notasi irisan Python
Singkatnya, titik dua ( :
) dalam notasi subscript ( subscriptable[subscriptarg]
) make slice notasi - yang memiliki argumen opsional, start
, stop
, step
:
sliceable[start:stop:step]
Mengiris Python adalah cara komputasi yang cepat untuk secara metodis mengakses bagian data Anda. Menurut pendapat saya, untuk menjadi programmer Python tingkat menengah, ini adalah salah satu aspek dari bahasa yang perlu Anda ketahui.
Untuk memulainya, mari kita tentukan beberapa istilah:
mulai: indeks awal dari slice, itu akan mencakup elemen pada indeks ini kecuali itu sama dengan berhenti , default ke 0, yaitu indeks pertama. Jika negatif, artinya memulai
n
item dari akhir.berhenti: indeks akhir dari slice, tidak termasuk elemen pada indeks ini, default untuk panjang urutan yang diiris, yaitu, hingga dan termasuk akhir.
langkah: jumlah kenaikan indeks, default ke 1. Jika negatif, Anda mengiris iterable secara terbalik.
Anda dapat membuat angka positif atau negatif ini. Arti bilangan positif itu langsung, tetapi untuk bilangan negatif, seperti halnya indeks dalam Python, Anda menghitung mundur dari ujung untuk memulai dan berhenti , dan untuk langkah ini , Anda cukup mengurangi indeks Anda. Contoh ini dari tutorial dokumentasi , tetapi saya telah sedikit memodifikasinya untuk menunjukkan item mana dalam urutan masing-masing referensi indeks:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
Untuk menggunakan notasi irisan dengan urutan yang mendukungnya, Anda harus menyertakan setidaknya satu titik dua dalam tanda kurung siku yang mengikuti urutan (yang sebenarnya menerapkan __getitem__
metode urutan, sesuai dengan model data Python .)
Notasi slice berfungsi seperti ini:
sequence[start:stop:step]
Dan ingat bahwa ada default untuk start , stop , dan step , jadi untuk mengakses default, cukup tinggalkan argumen.
Notasi irisan untuk mendapatkan sembilan elemen terakhir dari daftar (atau urutan lainnya yang mendukungnya, seperti string) akan terlihat seperti ini:
my_list[-9:]
Ketika saya melihat ini, saya membaca bagian dalam tanda kurung sebagai "kesembilan dari akhir, sampai akhir." (Sebenarnya, saya menyingkatnya secara mental sebagai "-9, pada")
Notasi lengkapnya adalah
my_list[-9:None:None]
dan untuk mengganti default (sebenarnya ketika step
negatif, stop
default adalah -len(my_list) - 1
, jadi None
untuk stop benar-benar berarti pergi ke mana pun langkah akhir membawanya ke):
my_list[-9:len(my_list):1]
Tanda titik dua ,, :
adalah yang memberi tahu Python bahwa Anda memberinya sepotong dan bukan indeks biasa. Itulah sebabnya cara idiomatis membuat salinan daftar yang dangkal di Python 2 adalah
list_copy = sequence[:]
Dan membersihkannya adalah dengan:
del my_list[:]
(Python 3 mendapat list.copy
dan list.clear
metode.)
step
negatif, standar untuk start
dan stop
berubahSecara default, ketika step
argumen kosong (atau None
), itu ditugaskan untuk +1
.
Tetapi Anda bisa memasukkan bilangan bulat negatif, dan daftar (atau sebagian besar slicables standar lainnya) akan diiris dari ujung ke awal.
Dengan demikian irisan negatif akan mengubah default untuk start
danstop
!
Saya ingin mendorong pengguna untuk membaca sumber serta dokumentasi. The kode sumber untuk sepotong objek dan logika ini ditemukan di sini . Pertama-tama kita menentukan apakah step
negatif:
step_is_negative = step_sign < 0;
Jika demikian, batas bawah -1
berarti kita mengiris hingga dan termasuk awal, dan batas atas adalah panjang minus 1, artinya kita mulai dari akhir. (Perhatikan bahwa semantik ini -1
adalah berbeda dari -1
yang pengguna dapat lulus indeks Python menunjukkan item terakhir.)
if (step_is_negative) { lower = PyLong_FromLong(-1L); if (lower == NULL) goto error; upper = PyNumber_Add(length, lower); if (upper == NULL) goto error; }
Kalau step
tidak positif, dan batas bawah akan menjadi nol dan batas atas (yang kita naiki tetapi tidak termasuk) panjang daftar irisan.
else { lower = _PyLong_Zero; Py_INCREF(lower); upper = length; Py_INCREF(upper); }
Kemudian, kita mungkin perlu menerapkan default untuk start
dan stop
- default maka untuk start
dihitung sebagai batas atas ketika step
negatif:
if (self->start == Py_None) { start = step_is_negative ? upper : lower; Py_INCREF(start); }
dan stop
, batas bawah:
if (self->stop == Py_None) { stop = step_is_negative ? lower : upper; Py_INCREF(stop); }
Anda mungkin merasa berguna untuk memisahkan pembentukan irisan dari meneruskannya ke list.__getitem__
metode ( itulah yang dilakukan kurung siku ). Sekalipun Anda bukan orang baru, itu membuat kode Anda lebih mudah dibaca sehingga orang lain yang mungkin harus membaca kode Anda dapat lebih mudah memahami apa yang Anda lakukan.
Namun, Anda tidak bisa hanya menetapkan beberapa bilangan bulat yang dipisahkan oleh titik dua ke sebuah variabel. Anda perlu menggunakan objek slice:
last_nine_slice = slice(-9, None)
Argumen kedua,, None
diperlukan, sehingga argumen pertama ditafsirkan sebagai start
argumen jika tidak maka akan menjadi stop
argumen .
Anda kemudian dapat meneruskan objek irisan ke urutan Anda:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
Sangat menarik bahwa rentang juga mengambil irisan:
>>> range(100)[last_nine_slice]
range(91, 100)
Karena irisan daftar Python membuat objek baru dalam memori, fungsi penting lainnya yang harus diperhatikan adalah itertools.islice
. Biasanya Anda ingin mengulang lebih dari satu irisan, tidak hanya itu dibuat secara statis dalam memori. islice
sempurna untuk ini. Peringatan, itu tidak mendukung argumen negatif untuk start
,, stop
atau step
, jadi jika itu masalah Anda mungkin perlu menghitung indeks atau membalikkan iterable terlebih dahulu.
length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)
dan sekarang:
>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]
Fakta bahwa irisan daftar membuat salinan adalah fitur dari daftar itu sendiri. Jika Anda mengiris objek canggih seperti DataFrame Pandas, itu dapat mengembalikan tampilan pada aslinya, dan bukan salinan.
Dan beberapa hal yang tidak langsung jelas bagi saya ketika saya pertama kali melihat sintaksis slicing:
>>> x = [1,2,3,4,5,6]
>>> x[::-1]
[6,5,4,3,2,1]
Cara mudah untuk membalik urutan!
Dan jika Anda ingin, untuk beberapa alasan, setiap item kedua dalam urutan terbalik:
>>> x = [1,2,3,4,5,6]
>>> x[::-2]
[6,4,2]
Dalam Python 2.7
Mengiris dengan Python
[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).
Memahami penugasan indeks sangat penting.
In forward direction, starts at 0 and ends at len-1
In backward direction, starts at -1 and ends at -len
Ketika Anda mengatakan [a: b: c], Anda mengatakan tergantung pada tanda c (maju atau mundur), mulai dari dan berakhir pada b (tidak termasuk elemen pada indeks ke-b). Gunakan aturan pengindeksan di atas dan ingat Anda hanya akan menemukan elemen dalam rentang ini:
-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1
Namun rentang ini berlanjut di kedua arah tanpa batas:
...,-len -2 ,-len-1,-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1, len, len +1, len+2 , ....
Sebagai contoh:
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
Jika pilihan a, b, dan c Anda memungkinkan tumpang tindih dengan rentang di atas saat Anda melintasi menggunakan aturan untuk a, b, c di atas Anda akan mendapatkan daftar dengan elemen (disentuh saat melintasi) atau Anda akan mendapatkan daftar kosong.
Satu hal terakhir: jika a dan b sama, maka Anda juga mendapatkan daftar kosong:
>>> 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]
yang menghasilkan[9]
Temukan tabel hebat ini di http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
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)
Setelah menggunakannya sedikit saya menyadari bahwa deskripsi yang paling sederhana adalah persis sama dengan argumen dalam satu for
lingkaran ...
(from:to:step)
Semua dari mereka adalah opsional:
(:to:step)
(from::step)
(from:to)
Kemudian pengindeksan negatif hanya perlu Anda menambahkan panjang string ke indeks negatif untuk memahaminya.
Ini tetap bekerja untuk saya ...
Saya merasa lebih mudah untuk mengingat cara kerjanya, dan kemudian saya bisa mengetahui kombinasi start / stop / step tertentu.
Ini penting untuk dipahami range()
terlebih dahulu:
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
Mulai dari start
, selangkah demi selangkah step
, jangan sampai stop
. Sangat sederhana.
Yang perlu diingat tentang langkah negatif adalah bahwa stop
selalu merupakan akhir yang dikecualikan, apakah itu lebih tinggi atau lebih rendah. Jika Anda ingin irisan yang sama dalam urutan yang berlawanan, itu jauh lebih bersih untuk melakukan pembalikan secara terpisah: misal 'abcde'[1:-2][::-1]
mengiris satu char dari kiri, dua dari kanan, lalu membalikkan. (Lihat juga reversed()
.)
Mengiris urutan adalah sama, kecuali itu pertama menormalkan indeks negatif, dan itu tidak pernah bisa keluar dari urutan:
TODO : Kode di bawah ini memiliki bug dengan "tidak pernah keluar dari urutan" ketika abs (langkah)> 1; Saya pikir saya menambalnya menjadi benar, tetapi sulit dimengerti.
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]
Jangan khawatir tentang is None
detailnya - ingat saja bahwa menghilangkan start
dan / atau stop
selalu melakukan hal yang benar untuk memberi Anda seluruh urutan.
Normalisasi indeks negatif pertama memungkinkan mulai dan / atau berhenti dihitung dari akhir secara independen: 'abcde'[1:-2] == 'abcde'[1:3] == 'bc'
meskipun range(1,-2) == []
. Normalisasi kadang-kadang dianggap sebagai "modulo the length", tetapi perhatikan itu menambahkan panjang hanya sekali: misalnya 'abcde'[-53:42]
hanya seluruh string.
this_is_how_slicing_works
tidak sama dengan irisan python. EG [0, 1, 2][-5:3:3]
akan mendapatkan [0] dengan python, tetapi list(this_is_how_slicing_works([0, 1, 2], -5, 3, 3))
mendapatkan [1].
range(4)[-200:200:3] == [0, 3]
tetapi list(this_is_how_slicing_works([0, 1, 2, 3], -200, 200, 3)) == [2]
. Saya if 0 <= i < len(seq):
adalah upaya untuk mengimplementasikan "tidak pernah keluar dari urutan" secara sederhana tetapi salah untuk langkah> 1. Saya akan menulis ulang nanti hari ini (dengan tes).
Saya menggunakan metode "indeks poin antar elemen" untuk memikirkannya sendiri, tetapi salah satu cara menggambarkannya yang terkadang membantu orang lain mendapatkannya adalah ini:
mylist[X:Y]
X adalah indeks dari elemen pertama yang Anda inginkan.
Y adalah indeks dari elemen pertama yang tidak Anda inginkan.
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 :
|--------------->
<---------------|
Saya harap ini akan membantu Anda untuk membuat model daftar dengan Python.
Referensi: http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
Notasi pengiris Python:
a[start:end:step]
start
dan end
, nilai-nilai negatif ditafsirkan sebagai relatif terhadap akhir urutan.end
menunjukkan posisi setelah elemen terakhir dimasukkan.[+0:-0:1]
.start
danend
Notasi meluas ke matriks (numpy) dan array multidimensi. Misalnya, untuk mengiris seluruh kolom yang dapat Anda gunakan:
m[::,0:2:] ## slice the first two columns
Irisan menyimpan referensi, bukan salinan, dari elemen array. Jika Anda ingin membuat salinan array secara terpisah, Anda dapat menggunakan deepcopy()
.
Ini hanya untuk beberapa info tambahan ... Pertimbangkan daftar di bawah ini
>>> l=[12,23,345,456,67,7,945,467]
Beberapa trik lain untuk membalik daftar:
>>> 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]
Ini adalah bagaimana saya mengajarkan irisan kepada pemula:
Memahami perbedaan antara pengindeksan dan pengirisan:
Wiki Python memiliki gambar yang luar biasa ini yang dengan jelas membedakan pengindeksan dan pengirisan.
Ini adalah daftar dengan enam elemen di dalamnya. Untuk memahami cara mengiris dengan lebih baik, pertimbangkan daftar itu sebagai satu set enam kotak yang ditempatkan bersama. Setiap kotak memiliki alfabet di dalamnya.
Pengindeksan seperti berurusan dengan isi kotak. Anda dapat memeriksa isi kotak apa pun. Tetapi Anda tidak dapat memeriksa isi beberapa kotak sekaligus. Anda bahkan dapat mengganti isi kotak. Tetapi Anda tidak bisa menempatkan dua bola dalam satu kotak atau mengganti dua bola sekaligus.
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
Mengiris seperti berurusan dengan kotak sendiri. Anda dapat mengambil kotak pertama dan meletakkannya di meja lain. Untuk mengambil kotak, yang perlu Anda ketahui adalah posisi awal dan akhir kotak.
Anda bahkan dapat mengambil tiga kotak pertama atau dua kotak terakhir atau semua kotak antara 1 dan 4. Jadi, Anda dapat memilih satu set kotak jika Anda tahu awal dan akhir. Posisi ini disebut posisi start dan stop.
Yang menarik adalah Anda bisa mengganti beberapa kotak sekaligus. Anda juga dapat menempatkan beberapa kotak di mana pun Anda suka.
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']
Mengiris dengan Langkah:
Sampai sekarang Anda telah memilih kotak secara terus menerus. Tetapi kadang-kadang Anda perlu mengambil dengan hati-hati. Misalnya, Anda dapat mengambil setiap kotak kedua. Anda bahkan dapat mengambil setiap kotak ketiga dari ujung. Nilai ini disebut ukuran langkah. Ini menunjukkan jarak antara pickup Anda yang berurutan. Ukuran langkah harus positif jika Anda memilih kotak dari awal hingga akhir dan sebaliknya.
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]: []
Bagaimana Python Angka Keluar Parameter Hilang:
Saat mengiris, jika Anda mengabaikan parameter apa pun, Python mencoba mengetahuinya secara otomatis.
Jika Anda memeriksa kode sumber CPython , Anda akan menemukan fungsi yang disebut PySlice_GetIndicesEx () yang menggambarkan indeks ke slice untuk parameter yang diberikan. Berikut adalah kode yang ekuivalen secara logis dengan Python.
Fungsi ini mengambil objek Python dan parameter opsional untuk mengiris dan mengembalikan panjang mulai, berhenti, langkah, dan iris untuk irisan yang diminta.
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)
Ini adalah kecerdasan yang ada di balik irisan. Karena Python memiliki fungsi bawaan yang disebut slice, Anda dapat melewati beberapa parameter dan memeriksa seberapa pintar menghitung parameter yang hilang.
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]
Catatan: Posting ini awalnya ditulis di blog saya, The Intelligence Behind Python Slices .
Sebagai aturan umum, menulis kode dengan banyak nilai indeks yang dikodekan menyebabkan kekacauan pembacaan dan pemeliharaan. Misalnya, jika Anda kembali ke kode setahun kemudian, Anda akan melihatnya dan bertanya-tanya apa yang Anda pikirkan ketika Anda menulisnya. Solusi yang ditampilkan hanyalah cara yang lebih jelas menyatakan apa yang sebenarnya dilakukan kode Anda. Secara umum, built-in slice () membuat objek slice yang dapat digunakan di mana pun slice diperbolehkan. Sebagai contoh:
>>> 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]
Jika Anda memiliki turunan slice s, Anda dapat memperoleh informasi lebih lanjut tentangnya dengan melihat masing-masing atribut s.start, s.stop, dan s.step. Sebagai contoh:
>>> a = slice(10, 50, 2) >>> a.start 10 >>> a.stop 50 >>> a.step 2 >>>
Untuk membuatnya sederhana, ingat irisan hanya memiliki satu bentuk:
s[start:end:step]
dan inilah cara kerjanya:
s
: sebuah objek yang dapat diirisstart
: indeks pertama untuk memulai iterasiend
: indeks terakhir, CATATAN end
indeks yang tidak akan dimasukkan dalam irisan yang dihasilkanstep
: pilih elemen setiap step
indeksHal lain yang impor: semua start
, end
, step
bisa dihilangkan! Dan jika mereka dihilangkan, nilai default mereka akan digunakan: 0
, len(s)
,1
sesuai.
Jadi kemungkinan variasi adalah:
# 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[:]
CATATAN: Jika start >= end
(hanya mempertimbangkan saat step>0
), Python akan mengembalikan potongan kosong[]
.
Bagian di atas menjelaskan fitur inti tentang cara kerja slice, dan itu akan berfungsi pada sebagian besar kesempatan. Namun, mungkin ada jebakan yang harus Anda perhatikan, dan bagian ini menjelaskannya.
Hal pertama yang membingungkan pelajar Python adalah bahwa indeks bisa negatif! Jangan panik: indeks negatif berarti menghitung mundur.
Sebagai contoh:
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].
Membuat hal-hal lebih membingungkan adalah itu step
bisa negatif juga!
Langkah negatif berarti mengembalikan array ke belakang: dari ujung ke awal, dengan indeks akhir disertakan, dan indeks awal dikecualikan dari hasilnya.
CATATAN : ketika langkah negatif, nilai default untuk start
adalah len(s)
(sementara end
tidak sama dengan 0
, karena s[::-1]
berisi s[0]
). Sebagai contoh:
s[::-1] # Reversed slice
s[len(s)::-1] # The same as above, reversed slice
s[0:len(s):-1] # Empty list
Terkejut: irisan tidak meningkatkan IndexError ketika indeks berada di luar jangkauan!
Jika indeks berada di luar jangkauan, Python akan mencoba yang terbaik untuk mengatur indeks ke 0
atau len(s)
sesuai dengan situasi. Sebagai contoh:
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]
Mari kita selesaikan jawaban ini dengan contoh, menjelaskan semua yang telah kita diskusikan:
# 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
Jawaban sebelumnya tidak membahas pemotongan multi-dimensi array yang dimungkinkan menggunakan paket NumPy yang terkenal :
Mengiris juga dapat diterapkan ke array multi-dimensi.
# 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
" Sebelum koma beroperasi pada dimensi pertama dan " 0:3:2
" setelah koma beroperasi pada dimensi kedua.
list
tetapi hanya di array
dalam Numpy
#!/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)
Anda dapat menjalankan skrip ini dan bereksperimen dengannya, di bawah ini adalah beberapa contoh yang saya dapatkan dari skrip.
+---+---+---+---+---+---+---+---+---+
| 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]
Saat menggunakan langkah negatif, perhatikan bahwa jawabannya digeser ke kanan oleh 1.
Otak saya sepertinya senang menerima yang lst[start:end]
berisi start
item -th. Saya bahkan dapat mengatakan bahwa itu adalah 'asumsi alami'.
Tetapi kadang-kadang keraguan merayap masuk dan otak saya meminta jaminan bahwa itu tidak mengandung end
unsur ke-5.
Pada saat-saat ini saya mengandalkan teorema sederhana ini:
for any n, lst = lst[:n] + lst[n:]
Properti cantik ini memberitahu saya bahwa lst[start:end]
tidak mengandung end
item -th karena ada di lst[end:]
.
Perhatikan bahwa teorema ini berlaku untuk n
semua. Misalnya, Anda dapat memeriksanya
lst = range(10)
lst[:-42] + lst[-42:] == lst
kembali True
.
Menurut pendapat saya, Anda akan memahami dan menghafal notasi string Python yang lebih baik jika Anda melihatnya dengan cara berikut (baca terus).
Mari kita bekerja dengan string berikut ...
azString = "abcdefghijklmnopqrstuvwxyz"
Bagi mereka yang tidak tahu, Anda dapat membuat substring dari azString
menggunakan notasiazString[x:y]
Berasal dari bahasa pemrograman lain, saat itulah akal sehat dikompromikan. Apa itu x dan y?
Saya harus duduk dan menjalankan beberapa skenario dalam pencarian saya untuk teknik menghafal yang akan membantu saya mengingat apa x dan y dan membantu saya mengiris string dengan benar pada upaya pertama.
Kesimpulan saya adalah bahwa x dan y harus dilihat sebagai indeks batas yang mengelilingi string yang ingin kita ekstra. Jadi kita harus melihat ekspresi itu azString[index1, index2]
atau bahkan lebih jelasazString[index_of_first_character, index_after_the_last_character]
.
Berikut adalah contoh visualisasi dari ...
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
Jadi yang harus Anda lakukan adalah mengatur index1 dan index2 ke nilai-nilai yang akan mengelilingi substring yang diinginkan. Misalnya, untuk mendapatkan substring "cdefgh", Anda dapat menggunakanazString[2:8]
, karena indeks di sisi kiri "c" adalah 2 dan yang pada ukuran kanan "h" adalah 8.
Ingatlah bahwa kami sedang menetapkan batasan. Dan batas-batas itu adalah posisi di mana Anda dapat menempatkan beberapa tanda kurung yang akan dililitkan di sekitar bidang seperti ini ...
ab [ cdefgh ] ij
Trik itu bekerja sepanjang waktu dan mudah diingat.
Sebagian besar jawaban sebelumnya membersihkan pertanyaan tentang notasi slice.
Sintaks pengindeksan diperpanjang yang digunakan untuk mengiris adalah aList[start:stop:step]
, dan contoh dasar adalah:
Contoh yang lebih mengiris: 15 Irisan Diperpanjang
Dalam Python, bentuk paling dasar untuk mengiris adalah sebagai berikut:
l[start:end]
di mana l
beberapa koleksi, start
merupakan indeks inklusif, dan end
merupakan indeks eksklusif.
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]
Ketika mengiris dari awal, Anda bisa menghilangkan indeks nol, dan ketika mengiris hingga akhir, Anda bisa menghilangkan indeks akhir karena itu berlebihan, jadi jangan bertele-tele:
In [5]: l[:3] == l[0:3]
Out[5]: True
In [6]: l[7:] == l[7:len(l)]
Out[6]: True
Bilangan bulat negatif berguna ketika melakukan offset relatif terhadap akhir koleksi:
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]
Adalah mungkin untuk memberikan indeks yang di luar batas ketika mengiris seperti:
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]
Ingatlah bahwa hasil mengiris koleksi adalah koleksi yang sama sekali baru. Selain itu, saat menggunakan notasi irisan dalam tugas, panjang tugas irisan tidak harus sama. Nilai sebelum dan sesudah irisan yang ditugaskan akan disimpan, dan koleksi akan menyusut atau tumbuh untuk mengandung nilai-nilai baru:
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]
Jika Anda menghilangkan indeks awal dan akhir, Anda akan membuat salinan koleksi:
In [14]: l_copy = l[:]
In [15]: l == l_copy and l is not l_copy
Out[15]: True
Jika indeks awal dan akhir dihilangkan saat melakukan operasi penugasan, seluruh konten koleksi akan diganti dengan salinan apa yang dirujuk:
In [20]: l[:] = list('hello...')
In [21]: l
Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.']
Selain mengiris dasar, juga dimungkinkan untuk menerapkan notasi berikut:
l[start:end:step]
di mana l
koleksi, start
adalah indeks inklusif, end
adalah indeks eksklusif, dan step
merupakan langkah yang dapat digunakan untuk mengambil setiap item ke dalam l
.
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]
Menggunakan step
menyediakan trik yang berguna untuk membalikkan koleksi dengan Python:
In [25]: l[::-1]
Out[25]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Dimungkinkan juga untuk menggunakan bilangan bulat negatif step
sebagai contoh berikut:
In[28]: l[::-2]
Out[28]: [9, 7, 5, 3, 1]
Namun, menggunakan nilai negatif untuk step
bisa menjadi sangat membingungkan. Selain itu, agar Pythonic , Anda harus menghindari menggunakan start
, end
dan step
dalam satu irisan. Dalam hal ini diperlukan, pertimbangkan melakukan ini dalam dua tugas (satu untuk mengiris, dan yang lainnya untuk melangkah).
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]
Saya ingin menambahkan satu Hello, World! contoh yang menjelaskan dasar-dasar irisan untuk pemula. Itu banyak membantu saya.
Mari kita daftar dengan enam nilai ['P', 'Y', 'T', 'H', 'O', 'N']
:
+---+---+---+---+---+---+
| P | Y | T | H | O | N |
+---+---+---+---+---+---+
0 1 2 3 4 5
Sekarang irisan paling sederhana dari daftar itu adalah sublists-nya. Notasi adalah [<index>:<index>]
dan kuncinya adalah membacanya seperti ini:
[ start cutting before this index : end cutting before this index ]
Sekarang jika Anda membuat sepotong [2:5]
daftar di atas, ini akan terjadi:
| |
+---+---|---+---+---|---+
| P | Y | T | H | O | N |
+---+---|---+---+---|---+
0 1 | 2 3 4 | 5
Anda membuat potongan sebelum elemen dengan indeks 2
dan potongan lain sebelum elemen dengan indeks 5
. Jadi hasilnya akan menjadi irisan antara dua potongan, daftar ['T', 'H', 'O']
.
Di bawah ini adalah contoh indeks string:
+---+---+---+---+---+
| H | e | l | p | A |
+---+---+---+---+---+
0 1 2 3 4 5
-5 -4 -3 -2 -1
str="Name string"
Contoh irisan: [mulai: akhir: langkah]
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
Di bawah ini adalah contoh penggunaannya:
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
Jika Anda merasa indeks negatif dalam mengiris membingungkan, berikut adalah cara yang sangat mudah untuk memikirkannya: cukup ganti dengan indeks negatif len - index
. Jadi misalnya, ganti -3 dengan len(list) - 3
.
Cara terbaik untuk menggambarkan apa yang dilakukan slicing secara internal adalah hanya menunjukkannya dalam kode yang mengimplementasikan operasi ini:
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)]
Teknik mengiris dasar adalah untuk menentukan titik awal, titik berhenti, dan ukuran langkah - juga dikenal sebagai langkah.
Pertama, kita akan membuat daftar nilai untuk digunakan dalam slicing kita.
Buat dua daftar untuk diiris. Yang pertama adalah daftar angka dari 1 hingga 9 (Daftar A). Yang kedua juga merupakan daftar angka, dari 0 hingga 9 (Daftar 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)
Indeks angka 3 dari A dan angka 6 dari B.
print(A[2])
print(B[6])
Irisan dasar
Sintaks pengindeksan diperpanjang yang digunakan untuk mengiris adalah aList [start: stop: step]. Argumen mulai dan argumen langkah default ke tidak ada - satu-satunya argumen yang diperlukan adalah berhenti. Apakah Anda memperhatikan bahwa ini mirip dengan bagaimana rentang digunakan untuk menentukan daftar A dan B? Ini karena objek irisan mewakili set indeks yang ditentukan oleh rentang (mulai, berhenti, langkah). Dokumentasi Python 3.4.
Seperti yang Anda lihat, mendefinisikan hanya berhenti mengembalikan satu elemen. Sejak awal tidak ada, ini berarti hanya mengambil satu elemen saja.
Penting untuk dicatat, elemen pertama adalah indeks 0, bukan indeks 1. Inilah sebabnya kami menggunakan 2 daftar untuk latihan ini. Elemen Daftar A diberi nomor sesuai dengan posisi ordinal (elemen pertama adalah 1, elemen kedua adalah 2, dll.) Sedangkan elemen Daftar B adalah angka yang akan digunakan untuk mengindeksnya ([0] untuk elemen pertama 0, dll.)
Dengan sintaks pengindeksan yang diperluas, kami mengambil rentang nilai. Misalnya, semua nilai diambil dengan titik dua.
A[:]
Untuk mengambil subset elemen, posisi awal dan berhenti harus ditentukan.
Dengan pola aList [start: stop], ambil dua elemen pertama dari Daftar A.
Saya tidak berpikir bahwa diagram tutorial Python (dikutip dalam berbagai jawaban lain) baik karena saran ini berfungsi untuk langkah positif, tetapi tidak untuk langkah negatif.
Ini adalah diagram:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
Dari diagram, saya berharap a[-4,-6,-1]
untuk menjadi yP
tetapi ty
.
>>> a = "Python"
>>> a[2:4:1] # as expected
'th'
>>> a[-4:-6:-1] # off by 1
'ty'
Yang selalu berhasil adalah berpikir dalam karakter atau slot dan menggunakan pengindeksan sebagai interval setengah terbuka - kanan-terbuka jika langkah positif, kiri-terbuka jika langkah negatif.
Dengan cara ini, saya bisa menganggapnya a[-4:-6:-1]
sebagai a(-6,-4]
terminologi interval.
+---+---+---+---+---+---+
| 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