Saya perlu penjelasan yang baik (referensi adalah plus) pada Python's iris notasi.
Untuk saya, notasi ini membutuhkan sedikit mengangkat.
Hal ini terlihat sangat kuat, tapi saya belum't cukup mendapatkan kepala saya sekitar itu.
It's cukup sederhana benar-benar:
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 langkah
nilai, yang dapat digunakan dengan salah satu di atas:
a[start:stop:step] # start through not past stop, by step
Titik kunci yang perlu diingat adalah bahwa berhenti
value merupakan nilai pertama yang tidak di slice yang dipilih. Jadi, perbedaan antara stop
dan start
adalah jumlah dari elemen yang dipilih (jika langkah
1, default).
Fitur lainnya adalah bahwa start
atau berhenti
mungkin negatif nomor, yang berarti menghitung dari akhir array, bukan dari awal. Jadi:
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, langkah
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 adalah jenis programmer jika ada item yang lebih sedikit dari yang anda minta. Misalnya, jika anda meminta untuk [: -2]
dan a
hanya berisi satu elemen, anda mendapatkan daftar kosong bukan sebuah kesalahan. Kadang-kadang anda akan lebih suka error, jadi anda harus menyadari bahwa ini mungkin terjadi.
slice()
objekMengiris operator []
adalah benar-benar digunakan dalam kode di atas dengan slice()
objek menggunakan :
notasi (yang hanya berlaku dalam waktu []
), yaitu:
a[start:stop:step]
setara dengan:
a[slice(start, stop, step)]
Sepotong benda juga berperilaku sedikit berbeda tergantung pada jumlah argumen, demikian pula untuk range()
, yaitu iris(berhenti)
dan iris(start, stop [langkah])
yang didukung.
Untuk melewati menentukan argumen yang diberikan, salah satu mungkin menggunakan None
, sehingga misalnya a[awal:]
adalah sama dengan a[slice(mulai, Tidak ada)]
atau [:: -1]
adalah sama dengan a[slice(Tidak ada, Tidak ada, -1)]
.
Sedangkan :
-berdasarkan notasi ini sangat membantu untuk mengiris sederhana, eksplisit penggunaan slice()
benda menyederhanakan program generasi mengiris.
The Python tutorial berbicara tentang hal itu (gulir ke bawah sedikit sampai anda mendapatkan ke bagian tentang mengiris).
ASCII art diagram ini berguna juga untuk mengingat bagaimana irisan bekerja:
+---+---+---+---+---+---+
| 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 untuk memikirkan indeks sebagai penunjuk antara karakter, dengan tepi kiri karakter pertama bernomor 0. Kemudian tepi kanan karakter terakhir dari string n karakter yang memiliki indeks n.
Menghitung kemungkinan-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 (tinggi-rendah)%langkahnya != 0
, maka titik akhir akan sedikit lebih rendah dari high-1
.
Jika tenang
adalah negatif, pemesanan berubah sedikit sejak kita're 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]]
Diperpanjang mengiris (dengan koma dan elips) yang sebagian besar hanya digunakan oleh struktur data (seperti NumPy); dasar urutan don't mendukung mereka.
>>> class slicee:
... def __getitem__(self, item):
... return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
Jawaban atas don't membahas iris tugas. Untuk memahami iris tugas, it's membantu untuk menambahkan konsep lain untuk ASCII art:
+---+---+---+---+---+---+
| 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, untuk sepotong dari nol sampai n, berpikir: "nol adalah awal, mulai dari awal dan mengambil 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']
Lain heuristik adalah, "untuk setiap irisan, menggantikan mulai dengan nol, berlaku sebelumnya heuristik untuk mendapatkan akhir dari daftar, kemudian menghitung 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 dari iris tugas adalah bahwa sejak mengiris pengembalian daftar, iris tugas membutuhkan daftar (atau lainnya 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
Aturan kedua dari iris tugas, yang juga dapat anda lihat di atas, adalah bahwa apapun bagian dari daftar dikembalikan dengan potongan pengindeksan, yang's porsi yang sama yang diubah oleh iris tugas:
>>> p[2:4]
['T','h']
>>> p[2:4] = ['t','r']
>>> p
['P','y','t','r','o','n']
Aturan ketiga iris tugas, daftar ditugaskan (iterable) doesn't harus memiliki panjang yang sama; diindeks slice ini cukup iris keluar dan diganti secara massal oleh fasilitas yang diberikan:
>>> 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 yang paling sulit untuk mendapatkan digunakan untuk tugas untuk mengosongkan irisan. Menggunakan heuristik 1 dan 2 itu's mudah untuk mendapatkan kepala anda sekitar indeks kosong slice:
>>> 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 kemudian setelah anda've terlihat bahwa, iris tugas kosong mengiris akal juga:
>>> 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 jumlah kedua iris (4), dimasukkan barang-barang yang selalu stack tepat terhadap 'o', bahkan ketika kita're menetapkan kosong slice. Jadi, posisi kosong iris tugas adalah perpanjangan logis dari posisi-posisi untuk non-kosong iris tugas.
Back up sedikit, apa yang terjadi ketika anda terus berjalan dengan prosesi menghitung potongan awal?
>>> 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 anda're selesai, anda're dilakukan; itu doesn't mulai mengiris mundur. Di Python anda don't mendapatkan negatif langkah kecuali anda secara eksplisit meminta mereka dengan menggunakan angka negatif.
>>> p[5:3:-1]
['n','o']
Ada yang aneh dengan konsekuensi-konsekuensi "setelah anda're selesai, anda're dilakukan" aturan:
>>> 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, Python mengiris aneh kesalahan-bukti:
>>> p[100:200]
[]
>>> p[int(2e99):int(1e99)]
[]
Ini dapat berguna kadang-kadang, tapi itu juga dapat menyebabkan agak aneh perilaku:
>>> 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, yang mungkin... atau mungkin tidak... menjadi apa yang anda berharap untuk ada!
Di bawah ini adalah teks asli saya menjawab. Hal ini telah berguna bagi banyak orang, jadi saya tidak't 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]
Hal ini dapat juga menjelaskan perbedaan antara mengiris dan pengindeksan.
Menjelaskan Python's iris notasi
Singkatnya, titik dua (
:
) di subskrip notasi (subscriptable[subscriptarg]
) membuat slice notasi - yang memiliki argumen opsional,mulai
,stop
,langkah
:
sliceable[start:stop:step]
Python mengiris adalah komputasi cara cepat untk mengakses bagian-bagian dari data anda. Menurut saya, untuk menjadi lebih perantara Python programmer, it's salah satu aspek dari bahasa yang perlu untuk menjadi akrab dengan.
Untuk mulai dengan, let's mendefinisikan beberapa istilah:
mulai: awal indeks dari sepotong, itu akan mencakup elemen pada indeks ini, kecuali jika itu adalah sama seperti berhenti, defaultnya 0, yaitu indeks pertama. Jika itu's negatif, itu berarti untuk memulai
n
barang-barang dari akhir. stop: ending indeks dari sepotong, itu tidak tidak termasuk elemen pada indeks ini, defaultnya panjang urutan diiris, yaitu, sampai dengan dan termasuk akhir. langkah: jumlah yang meningkat indeks, defaultnya 1. Jika itu's negatif, anda're mengiris atas iterable secara terbalik.Cara Pengindeksan Bekerja
Anda dapat membuat salah satu dari ini positif atau bilangan negatif. Arti dari bilangan positif adalah mudah, tapi untuk angka negatif, seperti indeks di Python, anda menghitung mundur dari akhir untuk mulai dan stop, dan langkah, anda hanya penurunan indeks. Contoh ini adalah dari dokumentasi's tutorial, tapi saya've dimodifikasi sedikit untuk menunjukkan item dalam urutan indeks masing-masing referensi:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
Untuk menggunakan slice notasi dengan urutan yang mendukung hal ini, anda harus menyertakan setidaknya satu usus besar dalam tanda kurung yang mengikuti urutan (yang sebenarnya menerapkan __getitem__
metode urutan, menurut Python model data.)
Iris notasi bekerja seperti ini:
sequence[start:stop:step]
Dan ingat bahwa ada default untuk mulai, stop, dan langkah, jadi untuk mengakses default, hanya meninggalkan argumen. Iris notasi untuk mendapatkan lalu sembilan elemen dari daftar (atau urutan lain yang mendukung, seperti string) akan terlihat seperti ini:
my_list[-9:]
Ketika saya melihat ini, saya membaca bagian di dalam kurung sebagai "ke-9 dari akhir, sampai akhir." (Sebenarnya, saya menyingkat itu mental sebagai "-9, di")
Notasi penuh adalah
my_list[-9:None:None]
dan untuk mengganti default (sebenarnya ketika langkah
adalah negatif, stop
's default adalah -len(my_list) - 1
, jadi None
untuk menghentikan benar-benar hanya berarti pergi ke mana akhir langkah membawanya ke):
my_list[-9:len(my_list):1]
The colon, :
, adalah apa yang memberitahu Python anda'kembali memberikan sepotong dan tidak teratur indeks. Yang's mengapa idiomatik cara membuat dangkal copy dari list di Python 2
list_copy = sequence[:]
Dan membersihkan mereka adalah dengan:
del my_list[:]
(Python 3 mendapat daftar.copy
dan daftar.jelas
metode.)
langkah
adalah negatif, default untuk mulai
dan stop
perubahanSecara default, ketika langkah
argumen kosong (atau Tidak
), hal ini ditetapkan ke +1
.
Tapi anda dapat lulus dalam bilangan bulat negatif, dan daftar (atau paling standar lainnya slicables) akan diiris dari akhir ke awal.
Dengan demikian negatif iris akan mengubah default untuk mulai
dan stop
!
Saya ingin mendorong pengguna untuk membaca sumber serta dokumentasi. Sumber kode untuk mengiris benda-benda dan logika ini ditemukan di sini. Pertama kita menentukan apakah langkah
lebih negatif:
step_is_negative = step_sign < 0; Jika demikian, batas bawah adalah
-1
berarti kita iris semua jalan sampai dengan dan termasuk awal, dan batas atas adalah suhu udara minus 1, artinya kita mulai di akhir. (Perhatikan bahwa semantik ini-1
adalah berbeda * dari-1
bahwa pengguna dapat lulus indeks di Python menunjukkan item terakhir.) jika (step_is_negative) { bawah = PyLong_FromLong(-1L); jika (lower == NULL) goto kesalahan;atas = PyNumber_Add(panjang, rendah); jika (atas == NULL) goto kesalahan; } Jika tidak
langkah
lebih positif, dan lebih rendah pasti akan menjadi nol dan batas atas (yang kita pergi hingga tapi tidak termasuk) panjang irisan daftar. else { bawah = _PyLong_Zero; Py_INCREF(lebih rendah); atas = panjang; Py_INCREF(atas); } Kemudian, kita mungkin perlu untuk menerapkan default untukmulai
danstop
- default kemudian untukmulai
dihitung sebagai batas atas ketikalangkah
lebih negatif: if (self->start == Py_None) { start = step_is_negative ? atas : bawah; Py_INCREF(start); } danstop
, batas bawah: if (self->menghentikan == Py_None) { menghentikan = step_is_negative ? bawah : nyaman; Py_INCREF(stop); }Memberikan anda irisan nama deskriptif!
Anda mungkin menemukan itu berguna untuk memisahkan membentuk iris lewat dari itu untuk
daftar.__getitem__
metode (yang's apa kurung do). Bahkan jika anda're bukan hal yang baru, itu membuat kode anda lebih mudah dibaca sehingga orang lain yang mungkin harus membaca kode anda dapat lebih mudah memahami apa yang anda're lakukan. Namun, anda dapat't hanya menetapkan beberapa bilangan bulat yang dipisahkan oleh titik dua variabel. Anda perlu menggunakan irisan objek:
last_nine_slice = slice(-9, None)
Argumen kedua, None
, diperlukan, sehingga argumen pertama adalah ditafsirkan sebagai start
argumen jika tidak maka akan berhenti
argumen.
Anda kemudian dapat lulus irisan objek urutan anda:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
It's menarik yang berkisar juga mengambil irisan:
>>> range(100)[last_nine_slice]
range(91, 100)
Sejak irisan Python buat daftar benda-benda baru di memori, fungsi penting lain yang harus diperhatikan adalah itertools.islice
. Biasanya anda'll ingin iterate atas sepotong, tidak hanya memiliki itu dibuat statis dalam memori. islice
adalah tempat yang sempurna untuk ini. Peringatan, itu doesn't dukungan negatif argumen untuk mulai
, stop
, atau langkah
, jadi jika yang's masalah anda mungkin perlu untuk menghitung indeks atau membalikkan iterable di muka.
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 daftar irisan membuat salinan adalah fitur daftar diri mereka sendiri. Jika anda're mengiris benda-benda canggih seperti Panda DataFrame, mungkin mengembalikan tampilan asli, dan bukan copy.
Dan beberapa hal-hal yang tidak't segera jelas bagi saya ketika saya pertama kali melihat mengiris sintaks:
>>> x = [1,2,3,4,5,6]
>>> x[::-1]
[6,5,4,3,2,1]
Cara mudah untuk membalikkan 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]
Di Python 2.7
Mengiris di 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).
Pengertian indeks tugas yang 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 dan berakhir pada b (tidak termasuk elemen di bth index). Menggunakan pengindeksan aturan di atas dan ingat, anda hanya akan menemukan unsur-unsur dalam kisaran ini:
-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1
Namun kisaran ini terus di kedua arah jauh:
...,-len -2 ,-len-1,-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1, len, len +1, len+2 , ....
Misalnya:
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 memungkinkan tumpang tindih dengan kisaran di atas saat anda melintasi menggunakan aturan untuk a,b,c di atas anda akan mendapatkan sebuah daftar dengan unsur-unsur (tersentuh selama traversal) atau anda akan mendapatkan daftar kosong.
Satu hal terakhir: jika a dan b adalah 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]
Menemukan ini di meja besar di http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
Python indeks dan irisan enam elemen list.
Indeks menghitung unsur-unsur, irisan menghitung ruang antara unsur-unsur.
Indeks dari belakang: -6 -5 -4 -3 -2 -1 a=[0,1,2,3,4,5] a[1:]==[1,2,3,4,5]
Indeks dari depan: 0 1 2 3 4 5 len(a)==6 a[:5]==[0,1,2,3,4]
+---+---+---+---+---+---+ a[0]==0[:-2]==[0,1,2,3]
| a | b | c | d | e | f | a[5]==5[1:2]==[1]
+---+---+---+---+---+---+ a[-1]==5[1:-1]==[1,2,3,4]
Slice dari depan: : 1 2 3 4 5 : a[-2]==4
Slice dari belakang: : -5 -4 -3 -2 -1 :
b=a[:]
b==[0,1,2,3,4,5] (dangkal copy)
Setelah menggunakan sedikit saya menyadari bahwa deskripsi sederhana adalah bahwa itu adalah persis sama dengan argumen dalam untuk
loop...
(from:to:step)
Salah satu dari mereka adalah opsional:
(:to:step)
(from::step)
(from:to)
Maka negatif pengindeksan hanya membutuhkan anda untuk menambah panjang string negatif indeks untuk memahaminya.
Ini bekerja untuk saya anyway...
Saya merasa lebih mudah untuk mengingat bagaimana cara kerjanya, dan kemudian saya dapat mengetahui setiap spesifik start/stop/langkah kombinasi.
It's instruktif untuk memahami range()
pertama:
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
, selisih dengan langkah
, tidak mencapai stop
. Sangat sederhana.
Hal yang perlu diingat tentang langkah negatif adalah bahwa stop
selalu dikecualikan akhir, apakah itu's lebih tinggi atau lebih rendah. Jika anda ingin slice yang sama untuk sebaliknya, it's jauh lebih bersih untuk dilakukan pembalikan secara terpisah: misal 'abcde'[1:-2][::-1]
irisan dari salah satu char dari kiri, kedua dari kanan, kemudian berbalik. (Lihat juga dibalik()
.)
Urutan mengiris adalah sama, kecuali itu pertama menormalkan negatif indeks, dan itu tidak akan pernah bisa pergi ke luar urutan:
TODO: kode di bawah ini memiliki bug dengan "tidak pernah pergi ke luar urutan" ketika abs(langkah)>1; I berpikir saya ditambal itu benar, tapi itu's sulit untuk memahami.
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]
Don't khawatir tentang Ada
rincian - hanya ingat bahwa menghilangkan start
dan/atau berhenti
selalu melakukan hal yang benar untuk memberikan anda seluruh urutan.
Normalisasi negatif indeks pertama memungkinkan memulai dan/atau berhenti harus dihitung dari akhir independen: 'abcde'[1:-2] == 'abcde'[1:3] == 'bc'
meskipun kisaran(1,-2) == []
.
Normalisasi ini kadang-kadang dianggap sebagai "modulo panjang", tapi catatan itu menambah panjang sekali saja: misal 'abcde'[-53:42]
hanya seluruh string.
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 berharap ini akan membantu anda untuk model daftar di Python.
Referensi: http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
Saya gunakan "indeks poin antara unsur-unsur" metode berpikir tentang hal itu sendiri, tetapi salah satu cara untuk menjelaskan hal itu yang kadang-kadang membantu orang lain mendapatkan ini:
mylist[X:Y]
X adalah indeks dari elemen pertama yang anda inginkan. Y adalah indeks dari elemen pertama anda don't ingin.
Python mengiris notasi:
a[start:end:step]
mulai
dan end
, nilai-nilai negatif yang ditafsirkan sebagai relatif terhadap akhir urutan.end
menunjukkan posisi setelah elemen terakhir yang harus disertakan.[+0:-0:1]
.awal
dan akhir
Notasi meluas ke (numpy) matriks dan array multidimensi. Misalnya, untuk mengiris seluruh kolom yang dapat anda gunakan:
m[::,0:2:] ## slice the first two columns
Irisan tahan referensi, bukan salinan, dari elemen array. Jika anda ingin membuat salinan terpisah sebuah array, anda dapat menggunakan deepcopy()
.
Ini adalah bagaimana saya mengajarkan potong untuk pemula:
Memahami perbedaan antara indeks dan mengiris:
Wiki Python memiliki gambar yang menakjubkan ini yang dengan jelas membedakan pengindeksan dan mengiris.
Ini adalah daftar dengan enam elemen di dalamnya. Untuk memahami mengiris baik, pertimbangkan daftar itu sebagai satu set dari enam kotak yang ditempatkan bersama-sama. Setiap kotak memiliki alfabet di dalamnya.
Pengindeksan lebih suka berurusan dengan isi dari kotak. Anda dapat memeriksa isi dari setiap kotak. Tapi anda bisa't memeriksa isi dari beberapa kotak sekaligus. Anda bahkan dapat mengganti isi dari kotak. Tapi anda bisa't tempat 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 letakkan pada meja lain. Untuk mengambil kotak itu, semua yang perlu anda ketahui adalah posisi awal dan akhir dari kotak.
Anda bahkan dapat mengambil tiga kotak atau dua kotak atau semua kotak antara 1 dan 4. Jadi, anda dapat memilih salah satu set kotak jika anda tahu awal dan akhir. Posisi ini disebut awal dan posisi berhenti.
Hal yang menarik adalah bahwa anda dapat 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 terus menerus. Tapi kadang-kadang anda perlu untuk mengambil discretely. Misalnya, anda dapat mengambil setiap kotak kedua. Anda bahkan dapat mengambil setiap kotak ketiga dari akhir. Nilai ini disebut ukuran langkah. Ini merupakan kesenjangan antara berturut-turut pickup. Ukuran langkah harus positif jika Anda memilih kotak dari awal sampai 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]: []
Cara Python Angka Keluar Hilang Parameter:
Ketika mengiris, jika anda pergi keluar setiap parameter, Python mencoba untuk mencari jalan keluar secara otomatis.
Jika anda memeriksa kode sumber CPython, anda akan menemukan sebuah fungsi yang disebut PySlice_GetIndicesEx() yang angka indeks untuk sepotong yang diberikan untuk setiap parameter. Berikut ini adalah logis setara kode dalam Python.
Fungsi ini membutuhkan Python obyek dan parameter opsional untuk mengiris dan kembali mulai, berhenti, melangkah, dan iris panjang untuk diminta slice.
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 terdapat di belakang iris. Karena Python memiliki fungsi built-in yang disebut slice, anda dapat melewati beberapa parameter dan memeriksa seberapa cerdas menghitung parameter.
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, Intelijen di Balik Python Irisan.
Ini hanya untuk beberapa tambahan info... Perhatikan daftar di bawah ini
>>> l=[12,23,345,456,67,7,945,467]
Beberapa trik lain untuk membalikkan 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]
Sebagai aturan umum, menulis kode dengan banyak hardcoded nilai indeks mengarah ke keterbacaan dan pemeliharaan berantakan. Misalnya, jika anda datang kembali ke kode setahun kemudian, anda akan melihat itu dan bertanya-tanya apa yang anda pikirkan ketika anda menulisnya. Solusi yang ditunjukkan ini hanyalah sebuah cara untuk lebih jelas menyatakan apa kode anda benar-benar melakukan. Secara umum, built-in slice() menciptakan sepotong benda yang dapat digunakan di mana saja sepotong diperbolehkan. Misalnya:
>>> 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 sepotong misalnya s, anda bisa mendapatkan informasi lebih lanjut tentang hal itu dengan melihat s.mulai, s.berhenti, dan s.langkah atribut masing-masing. Misalnya:
a = slice(10, 50, 2) a.mulai 10 a.berhenti 50 a.langkah 2
Untuk membuatnya sederhana, ingat slice hanya memiliki satu bentuk:
s[start:end:step]
dan berikut adalah cara kerjanya:
s
: sebuah benda yang dapat diirisstart
: indeks pertama untuk memulai iterasiend
: indeks terakhir, PERHATIKAN bahwa end
index tidak akan disertakan dalam menghasilkan irislangkah
: memilih setiap elemen langkah
indexLain import hal: semua mulai
,end
, langkah
dapat 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
(mengingat hanya ketika langkah>0
), Python akan kembali kosong slice []
.
Bagian di atas menjelaskan fitur inti tentang bagaimana sepotong bekerja, dan itu akan bekerja pada sebagian besar kesempatan. Namun, ada dapat menjadi perangkap anda harus berhati-hati, dan bagian ini menjelaskan mereka.
Hal pertama yang membingungkan Python peserta didik adalah sebuah indeks yang dapat menjadi negatif! Don't panik: indeks negatif berarti menghitung mundur.
Misalnya:
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 yang lebih membingungkan adalah bahwa langkah
bisa negatif juga!
Sebuah langkah negatif berarti iterate array mundur: dari akhir ke awal, dengan akhir indeks disertakan, dan start index yang dikeluarkan dari hasil.
NOTE: jika langkah negatif, nilai default untuk start
adalah len(s)
(sementara end
tidak sama dengan 0
, karena s[::-1]
berisi s[0]
). Misalnya:
s[::-1] # Reversed slice
s[len(s)::-1] # The same as above, reversed slice
s[0:len(s):-1] # Empty list
Heran: slice tidak menaikkan IndexError ketika indeks berada di luar jangkauan!
Jika indeks berada di luar jangkauan, Python akan mencoba yang terbaik untuk mengatur naik ke 0
atau len(s)
sesuai dengan situasi. Misalnya:
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]
Let's ini selesai menjawab dengan contoh-contoh, yang menjelaskan segala sesuatu yang telah kita bahas:
# 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
Sebelumnya jawaban don't mendiskusikan multi-dimensi array mengiris yang mungkin menggunakan terkenal NumPy paket:
Mengiris juga dapat diterapkan untuk 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.
#!/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 script ini dan bereksperimen dengan itu, di bawah ini adalah beberapa contoh yang saya dapatkan dari script.
+---+---+---+---+---+---+---+---+---+
| 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]
Ketika menggunakan langkah negatif, pemberitahuan bahwa jawabannya adalah bergeser ke kanan sebesar 1.