Banyak programmer Python mungkin tidak menyadari bahwa sintaks dari while
loop dan for
loop menyertakan else:
klausa opsional :
for val in iterable:
do_something(val)
else:
clean_up()
Tubuh else
klausa adalah tempat yang baik untuk beberapa jenis tindakan pembersihan, dan dijalankan pada terminasi loop normal: Yaitu, keluar dari loop dengan return
atau break
melewatkan else
klausa; keluar setelah continue
menjalankannya. Aku tahu ini hanya karena saya hanya melihat ke atas (lagi), karena saya tidak pernah bisa mengingat saat ini else
klausul dijalankan.
Selalu? Pada "kegagalan" dari loop, seperti namanya? Pemutusan hubungan kerja reguler? Bahkan jika loop keluar dengan return
? Saya tidak pernah bisa sepenuhnya yakin tanpa mencarinya.
Saya menyalahkan ketidakpastian yang terus-menerus saya pada pilihan kata kunci: Saya menemukan else
sangat tidak kesalahan untuk semantik ini. Pertanyaan saya bukanlah "mengapa kata kunci ini digunakan untuk tujuan ini" (yang mungkin akan saya pilih untuk ditutup, meskipun hanya setelah membaca jawaban dan komentar), tetapi bagaimana saya bisa memikirkan else
kata kunci sehingga semantiknya masuk akal, dan saya dapatkah karena itu mengingatnya?
Saya yakin ada cukup banyak diskusi tentang ini, dan saya bisa membayangkan bahwa pilihan dibuat untuk konsistensi dengan klausa try
pernyataan else:
(yang saya juga harus melihat ke atas), dan dengan tujuan tidak menambah daftar Kata-kata Python cadangan. Mungkin alasan untuk memilih else
akan memperjelas fungsinya dan membuatnya lebih mudah diingat, tapi saya setelah menghubungkan nama dengan fungsi, bukan setelah penjelasan historis semata.
Jawaban atas pertanyaan ini , yang secara singkat ditutup oleh pertanyaan saya sebagai duplikat, berisi banyak cerita belakang yang menarik. Pertanyaan saya memiliki fokus yang berbeda (bagaimana menghubungkan semantik spesifik else
dengan pilihan kata kunci), tetapi saya merasa harus ada tautan ke pertanyaan ini di suatu tempat.
sumber
else
berarti pada dasarnya, "jika kondisi kelanjutan gagal". Dalam perulangan tradisional, kondisi kelanjutan biasanyai < 42
, dalam hal ini, Anda dapat melihat bagian itu sebagaiif i < 42; execute the loop body; else; do that other thing
break
. Case use kanonik adalah ketika loop mencari sesuatu, dan rusak ketika menemukannya. Inielse
dieksekusi hanya jika tidak ada yang ditemukan.Jawaban:
(Ini terinspirasi oleh jawaban @ Mark Tolonen.)
Sebuah
if
pernyataan menjalankan nyaelse
klausul jika kondisinya false. Secara identik,while
loop menjalankan klausa lain jika kondisinya bernilai false.Aturan ini cocok dengan perilaku yang Anda jelaskan:
break
pernyataan, Anda keluar dari loop tanpa mengevaluasi kondisinya, sehingga kondisinya tidak dapat mengevaluasi false dan Anda tidak pernah menjalankan klausa yang lain.continue
pernyataan, Anda mengevaluasi kondisi lagi, dan melakukan apa yang biasanya Anda lakukan di awal perulangan lingkaran. Jadi, jika kondisinya benar, Anda terus mengulang, tetapi jika itu salah Anda menjalankan klausa lain.return
, tidak mengevaluasi kondisi dan karena itu tidak menjalankan klausa lain.for
loop berperilaku dengan cara yang sama. Anggap saja kondisinya benar jika iterator memiliki lebih banyak elemen, atau salah jika tidak.sumber
elif
pernyataan. Ada jawaban yang sesuai, dan memiliki satu upvote bersih.break
, dalam halelse
ini tidak akan berjalan tetapi kondisinya False. Demikian pula denganfor
loop dapatbreak
pada elemen terakhir.Lebih baik memikirkannya seperti ini:
else
Blok akan selalu dieksekusi jika semuanya berjalan dengan baik difor
blok sebelumnya sehingga mencapai kelelahan.Tepat dalam konteks ini berarti tidak
exception
, tidakbreak
, tidakreturn
. Pernyataan apa pun yang membajak kendalifor
akan menyebabkanelse
blok dilewati.Kasus penggunaan umum ditemukan ketika mencari item dalam
iterable
, yang pencariannya dimatikan ketika item ditemukan atau"not found"
bendera dinaikkan / dicetak melaluielse
blok berikut :A
continue
tidak membajak kontrol darifor
, jadi kontrol akan dilanjutkan keelse
setelahfor
habis.sumber
else
klausa akan dieksekusi ketika segalanya tidak berjalan dengan benar, bukan? Saya sudah bingung lagi ...else
]", karenaelse
dijalankan ketika tidak ada kondisi di loop untuk mengevaluasi ke True, seperti yang saya tunjukkan dalam jawaban sayaFalse
. Jadi pertanyaan tentang bagaimanafor
yang rusak tergantung pada kasus penggunaan.else
dalam python). Anda memberikan ringkasan intuitif yang bagus tentang apa yangelse
dilakukan, @Moses, tetapi tidak tentang bagaimana kami dapat mengaitkan perilaku ini dengan "lain". Jika kata kunci yang berbeda digunakan (misalnya,nobreak
seperti yang disebutkan dalam jawaban untuk pertanyaan terkait), akan lebih mudah untuk dimengerti.if
/while
kondisi menilai false ataufor
kehabisan item.break
ada loop berisi (setelahelse
).continue
kembali dan mengevaluasi kondisi loop lagi.Kapan suatu
if
eksekusielse
? Ketika kondisinya salah. Persis sama untukwhile
/else
. Jadi Anda dapat menganggapwhile
/else
hanya sebagaiif
yang terus menjalankan kondisi sebenarnya hingga bernilai salah. Abreak
tidak mengubah itu. Itu hanya melompat keluar dari loop yang berisi tanpa evaluasi. Theelse
hanya dijalankan jika mengevaluasi yangif
/while
kondisi adalah palsu.The
for
mirip, kecuali kondisi yang palsu melelahkan iterator nya.continue
danbreak
jangan dieksekusielse
. Itu bukan fungsi mereka. Thebreak
keluar loop mengandung. Thecontinue
kembali ke atas loop yang mengandung, di mana kondisi loop dievaluasi. Ini adalah tindakan mengevaluasiif
/while
ke false (ataufor
tidak memiliki item lagi) yang dijalankanelse
dan tidak ada cara lain.sumber
else
klausa dieksekusi jika loop keluar dengancontinue
(atau biasanya), tetapi tidak jika kita keluar denganbreak
. Kehalusan ini adalah alasan mengapa saya mencoba untuk benar-benarelse
menangkap apa yang ditangkap dan apa yang tidak.Inilah arti dasarnya:
Ini adalah cara yang lebih baik untuk menulis pola umum ini:
The
else
klausul tidak akan dieksekusi jika adareturn
karenareturn
daun fungsi, seperti yang dimaksudkan untuk. Satu-satunya pengecualian untuk apa yang mungkin Anda pikirkan adalahfinally
, yang tujuannya adalah untuk memastikan bahwa itu selalu dieksekusi.continue
tidak ada hubungannya dengan masalah ini. Ini menyebabkan iterasi saat ini dari loop ke ujung yang mungkin terjadi untuk mengakhiri seluruh loop, dan jelas dalam kasus itu loop tidak berakhir dengan abreak
.try/else
serupa:sumber
Jika Anda menganggap loop Anda sebagai struktur yang mirip dengan ini (kode pseudo-agak):
mungkin lebih masuk akal. Loop pada dasarnya hanyalah
if
pernyataan yang diulang sampai kondisinyafalse
. Dan ini adalah poin penting. Loop memeriksa kondisinya dan melihat bahwa itufalse
, sehingga menjalankanelse
(seperti normalif/else
) dan kemudian loop dilakukan.Jadi perhatikan bahwa
else
hanya eksekusi yang dieksekusi ketika kondisi diperiksa . Itu berarti bahwa jika Anda keluar dari tubuh loop di tengah eksekusi dengan misalnya areturn
atau abreak
, karena kondisi tidak dicentang lagi,else
kasing tidak akan dieksekusi.A
continue
di sisi lain menghentikan eksekusi saat ini dan kemudian melompat kembali untuk memeriksa kondisi loop lagi, itulah sebabnyaelse
dapat dicapai dalam skenario ini.sumber
end
label dan letakkan saja bagiangoto loop
dalamif
tubuhnya. Mungkin bahkan ketinggalan jaman dengan meletakkannyaif
pada garis yang sama dengan labelnya, dan tiba-tiba terlihat seperti orignal.Momen getcha saya dengan
else
klausa loop adalah ketika saya menonton ceramah oleh Raymond Hettinger , yang menceritakan sebuah kisah tentang bagaimana dia pikir itu seharusnya dipanggilnobreak
. Lihatlah kode berikut, menurut Anda apa yang akan dilakukan?Apa yang akan Anda duga? Nah, bagian yang mengatakan
nobreak
hanya akan dieksekusi jika sebuahbreak
pernyataan tidak mengenai loop.sumber
Biasanya saya cenderung memikirkan struktur loop seperti ini:
Menjadi sangat mirip sejumlah variabel
if/elif
pernyataan:Dalam hal ini
else
pernyataan pada for loop bekerja persis sepertielse
pernyataan pada rantaielif
s, ia hanya mengeksekusi jika tidak ada kondisi sebelum mengevaluasi ke True. (atau hentikan eksekusi denganreturn
atau pengecualian) Jika loop saya tidak sesuai dengan spesifikasi ini biasanya saya memilih untuk tidak menggunakanfor: else
karena alasan yang tepat Anda memposting pertanyaan ini: itu tidak intuitif.sumber
Yang lain sudah menjelaskan mekanika
while/for...else
, dan referensi bahasa Python 3 memiliki definisi otoritatif (lihat sementara dan untuk ), tetapi ini adalah mnemonik pribadi saya, FWIW. Saya kira kuncinya bagi saya adalah untuk memecah ini menjadi dua bagian: satu untuk memahami arti darielse
dalam kaitannya dengan loop kondisional, dan satu untuk memahami kontrol loop.Saya merasa paling mudah untuk memulai dengan memahami
while...else
:The
for...else
mnemonic pada dasarnya sama:Dalam kedua kasus,
else
bagian hanya tercapai setelah tidak ada lagi item untuk diproses, dan item terakhir telah diproses secara teratur (yaitu tidak adabreak
ataureturn
). Acontinue
hanya kembali dan melihat apakah ada item lagi. Mnemonik saya untuk aturan ini berlaku untuk keduanyawhile
danfor
:- dengan "loop back to start" yang berarti, jelas, awal dari loop di mana kami memeriksa apakah ada lebih banyak item di iterable, sehingga sejauh
else
menyangkut,continue
benar-benar tidak memainkan peran sama sekali.sumber
else
juga dapat digunakan untuk melakukan sesuatu ketika Anda hanya selesai dengan semua item. Contohnya termasuk menulis entri log, memperbarui antarmuka pengguna, atau memberi sinyal beberapa proses lain yang telah Anda lakukan. Apa saja, sungguh. Juga, beberapa bagian kode memiliki case "berhasil" dengan bagianbreak
dalam loop, danelse
digunakan untuk menangani case "error" di mana Anda tidak menemukan item yang cocok selama iterasi (mungkin itu yang Anda pikirkan dari?).else
blok loop , atau melacak hasilnya menggunakan cara lain. Saya pada dasarnya setuju, saya hanya mengatakan saya tidak tahu bagaimana orang menggunakan fitur ini dan oleh karena itu saya ingin menghindari membuat asumsi apakahelse
skenario " menangani kasus yang berhasil" atau skenario "else
menangani kasus yang tidak berhasil" lebih umum. Tapi Anda punya poin bagus, jadi komentarnya terunggul!Dalam pengembangan Test-driven (TDD), saat menggunakan Transformation Priority Premise paradigma , Anda memperlakukan loop sebagai generalisasi pernyataan bersyarat.
Pendekatan ini menggabungkan dengan baik dengan sintaks ini, jika Anda hanya mempertimbangkan pernyataan sederhana
if/else
(tidakelif
):menggeneralisasi ke:
baik.
Dalam bahasa lain, langkah-langkah TDD dari satu kasus ke kasus dengan koleksi membutuhkan lebih banyak refactoring.
Ini adalah contoh dari blog 8thlight :
Dalam artikel yang ditautkan di blog 8thlight, kata Bungkus Kata dianggap: menambahkan jeda baris ke string (
s
variabel dalam cuplikan di bawah) untuk membuatnya cocok dengan lebar yang diberikan (length
variabel dalam cuplikan di bawah). Pada satu titik implementasi terlihat sebagai berikut (Jawa):dan tes berikutnya, yang saat ini gagal adalah:
Jadi kami memiliki kode yang berfungsi secara kondisional: ketika suatu kondisi tertentu terpenuhi, baris baru ditambahkan. Kami ingin meningkatkan kode untuk menangani beberapa jeda baris. Solusi yang disajikan dalam artikel ini mengusulkan untuk menerapkan transformasi (jika-> sementara) , namun penulis membuat komentar bahwa:
yang memaksa untuk melakukan lebih banyak perubahan pada kode dalam konteks satu tes gagal:
Dalam TDD kami ingin menulis kode sesedikit mungkin untuk membuat tes lulus. Berkat sintaksis Python, transformasi berikut dimungkinkan:
dari:
untuk:
sumber
Cara saya melihatnya,
else:
menyala ketika Anda beralih melewati ujung loop.Jika Anda
break
ataureturn
atauraise
Anda tidak iterate masa akhir loop, Anda berhenti immeadiately, dan dengan demikianelse:
blok tidak akan berjalan. Jika Andacontinue
masih mengulangi melewati akhir loop, karena terus hanya melompat ke iterasi berikutnya. Itu tidak menghentikan loop.sumber
goto
bagian atas pada kesuksesan.) Tapi itu versi yang lebih pendek dari jawaban terpilih ...Pikirkan
else
klausa sebagai bagian dari konstruksi loop;break
keluar sama sekali dari konstruk loop, dan dengan demikian melompatielse
klausa.Tapi sungguh, pemetaan mental saya hanyalah bahwa itu adalah versi 'terstruktur' dari pola C / C ++ pola:
Jadi ketika saya menemukan
for...else
atau menulis sendiri, daripada memahaminya secara langsung , saya secara mental menerjemahkannya ke dalam pemahaman pola di atas dan kemudian mencari tahu bagian mana dari sintaksis python yang dipetakan ke bagian mana dari pola tersebut.(Saya menempatkan 'terstruktur' dalam kutipan menakut-nakuti karena perbedaannya bukan apakah kode terstruktur atau tidak terstruktur, tetapi hanya apakah ada kata kunci dan tata bahasa yang didedikasikan untuk struktur tertentu)
sumber
else
? Jika Anda bermaksuddone:
label untuk berdiri proksi atauelse:
, saya yakin Anda memilikinya persis mundur.done:
label. Korespondensi keseluruhan, mungkin, paling baik dikatakan sebagai berikut: Python memilikielse
konstruksi -on-loop sehingga Anda dapat mengekspresikan pola aliran kontrol ini tanpagoto
.else
menghindari.Jika Anda memasangkan
else
denganfor
, itu bisa membingungkan. Saya tidak berpikir kata kuncielse
adalah pilihan yang bagus untuk sintaks ini, tetapi jika Anda memasangkanelse
denganif
yang berisibreak
, Anda dapat melihatnya benar-benar masuk akal.else
hampir tidak berguna jika tidak adaif
pernyataan sebelumnya dan saya percaya ini sebabnya desainer sintaks memilih kata kunci.Biarkan saya menunjukkannya dalam bahasa manusia.
sumber
Cara saya berpikir tentang hal itu, kuncinya adalah mempertimbangkan makna
continue
daripadaelse
.Kata kunci lain yang Anda sebutkan keluar dari loop (keluar secara tidak normal) sementara
continue
tidak, itu hanya melompati sisa blok kode di dalam loop. Fakta bahwa ia dapat mendahului terminasi loop adalah insidental: terminasi ini sebenarnya dilakukan dengan cara normal dengan mengevaluasi ekspresi kondisional loop.Maka Anda hanya perlu mengingat bahwa
else
klausa dieksekusi setelah terminasi loop normal.sumber
sumber