Saya mengerti bagaimana konstruksi ini bekerja:
for i in range(10):
print(i)
if i == 9:
print("Too big - I'm giving up!")
break;
else:
print("Completed successfully")
Tapi saya tidak mengerti mengapa else
digunakan sebagai kata kunci di sini, karena itu menyarankan kode yang dimaksud hanya berjalan jika for
blok tidak lengkap, yang merupakan kebalikan dari apa yang dilakukannya! Tidak peduli bagaimana saya memikirkannya, otak saya tidak dapat berkembang dengan mulus dari for
pernyataan ke else
blok. Bagi saya, continue
atau continuewith
lebih masuk akal (dan saya mencoba melatih diri saya untuk membacanya seperti itu).
Saya bertanya-tanya bagaimana coders Python membaca konstruksi ini di kepala mereka (atau dengan keras, jika Anda suka). Mungkin saya melewatkan sesuatu yang akan membuat blok kode seperti itu lebih mudah diuraikan?
python
if-statement
for-loop
for-else
Kent Boogaart
sumber
sumber
break
banyak digunakan dalam loop "Saya telah menemukannya" , Anda dapat menerjemahkannya ke "jika tidak ditemukan" , yang tidak jauh dari yangelse
berbunyifor ... else foo()
dan hanyafoo()
mencari loop for?" Dan jawabannya adalah mereka berperilaku berbeda hanya jika loop berisibreak
(seperti yang dijelaskan secara rinci di bawah).Jawaban:
Ini adalah konstruksi yang aneh bahkan untuk coders Python berpengalaman. Ketika digunakan bersama dengan untuk-loop pada dasarnya berarti "menemukan beberapa item di iterable, kalau tidak ada yang ditemukan lakukan ...". Seperti dalam:
Tetapi setiap kali Anda melihat konstruk ini, alternatif yang lebih baik adalah merangkum pencarian dalam suatu fungsi:
Atau gunakan pemahaman daftar:
Secara semantik tidak setara dengan dua versi lainnya, tetapi berfungsi cukup baik dalam kode kritis non-kinerja di mana tidak masalah apakah Anda mengulangi seluruh daftar atau tidak. Orang lain mungkin tidak setuju, tetapi saya pribadi tidak akan pernah menggunakan blok for-else atau sementara-else dalam kode produksi.
Lihat juga [Ide Python] Ringkasan untuk ... utas lainnya
sumber
for
contoh loop, dan ingin menggunakan ekspresi generator / daftar pemahaman, maka Anda inginnext((o for o in objects if o.key == search_key), None)
atau membungkusnya dalamtry
/except
dan tidak menggunakan nilai default sebagai gantiif
/else
.for/else
konstruk.else
dipasangkan denganfor
dan saya tidak tahu itu legal.break
pernyataan dijalankan dengan eksplisit seperti dalam contoh ini. Dari dokumen di atas: "else
Klausa memiliki masalah lain yang dirasakan: jika tidak adabreak
dalam loop,else
klausa secara fungsional berlebihan." misfor x in [1, 2, 3]:\n print x\n else:\n print 'this executes due to no break'
Konstruk yang umum adalah menjalankan loop sampai sesuatu ditemukan dan kemudian keluar dari loop. Masalahnya adalah bahwa jika saya keluar dari loop atau loop berakhir saya harus menentukan kasus mana yang terjadi. Salah satu metode adalah membuat flag atau variabel toko yang akan membiarkan saya melakukan tes kedua untuk melihat bagaimana loop keluar.
Sebagai contoh, asumsikan bahwa saya perlu mencari melalui daftar dan memproses setiap item sampai item bendera ditemukan dan kemudian berhenti memproses. Jika item bendera hilang maka pengecualian perlu dinaikkan.
Menggunakan Python
for
...else
konstruk yang Anda milikiBandingkan ini dengan metode yang tidak menggunakan gula sintaksis ini:
Dalam kasus pertama
raise
terikat erat dengan for loop yang bekerja dengannya. Yang kedua mengikat tidak sekuat dan kesalahan dapat terjadi selama pemeliharaan.sumber
Python: the good parts
buku.process(i)
terjadi untuk setiap item dimylist
ketat sebelumnyatheflag
, dan tidak untuktheflag
dirinya sendiri? Apakah itu yang dimaksudkan?process
akan mengeksekusi pada setiapi
yang ada dalam daftar sebelumtheflag
tercapai, itu tidak akan dieksekusi pada elemen dalam daftar setelahtheflag
, dan itu tidak akan dieksekusi padatheflag
.Ada presentasi yang sangat baik oleh Raymond Hettinger, berjudul Transforming Code into Beautiful, Idiomatic Python , di mana ia secara singkat membahas sejarah
for ... else
konstruk. Bagian yang relevan adalah "Membedakan beberapa titik keluar dalam loop" mulai pukul 15:50 dan berlanjut selama sekitar tiga menit. Inilah poin-poin utamanya:for ... else
konstruk ditemukan oleh Donald Knuth sebagai pengganti tertentuGOTO
kasus penggunaan;else
kata kunci masuk akal karena "itulah yang digunakan Knuth, dan orang-orang tahu, pada saat itu, semua [for
pernyataan] telah menyematkanif
dan diGOTO
bawahnya, dan mereka mengharapkannyaelse
;"Jadi, jika pertanyaannya adalah, "Mengapa mereka tidak mengubah kata kunci ini?" maka Cat Plus Plus mungkin memberikan jawaban yang paling akurat - pada titik ini, akan terlalu merusak kode yang ada untuk menjadi praktis. Tetapi jika pertanyaan yang benar-benar Anda tanyakan adalah mengapa
else
digunakan kembali, pertama, sepertinya itu ide yang bagus pada saat itu.Secara pribadi, saya suka kompromi komentar
# no break
in-line di mana punelse
bisa keliru, sekilas, sebagai milik di dalam lingkaran. Cukup jelas dan ringkas. Opsi ini mendapat penyebutan singkat dalam ringkasan yang dihubungkan Bjorn di akhir jawabannya:* Kutipan bonus dari bagian video itu: "Sama seperti jika kita memanggil fungsi lambda , tidak ada yang akan bertanya, 'Apa yang lambda lakukan?'"
sumber
Karena mereka tidak ingin memperkenalkan kata kunci baru ke bahasa. Masing-masing mencuri pengidentifikasi dan menyebabkan masalah kompatibilitas ke belakang, jadi biasanya merupakan upaya terakhir.
sumber
finally
akan menjadi pilihan yang lebih baik dalam kasus itu. Apakah kata kunci akhirnya belum ada pada saat konstruksi ini diperkenalkan?finally
tidak jauh lebih baik, karena itu menyiratkan blok akan selalu dieksekusi setelah loop, dan itu tidak (karena itu akan berlebihan dengan hanya meletakkan kode untuk dijalankan setelah loop).finally
karena klausa lain dieksekusi juga ketikacontinue
digunakan dalam for loop - yang mungkin berkali-kali dan tidak hanya di akhir.else
klausa tidak terpengaruh olehcontinue
( dokumen dan kode pengujian )else
dieksekusi hanya ketikacontinue
itu adalah satu untuk iterasi terakhir.Untuk membuatnya sederhana, Anda bisa memikirkannya seperti itu;
break
perintah dalamfor
loop,else
bagian itu tidak akan dipanggil.break
perintah dalamfor
loop,else
bagian itu akan dipanggil.Dengan kata lain, jika untuk iterasi loop tidak "rusak" dengan
break
,else
bagian itu akan dipanggil.sumber
else
blok juga tidak akan dijalankan jika tubuh loop menimbulkan pengecualian.Cara termudah yang saya temukan untuk 'mendapatkan' apa yang dilakukan oleh orang lain, dan yang lebih penting, kapan menggunakannya, adalah berkonsentrasi pada di mana pernyataan break melompat ke. Konstruksi For / else adalah blok tunggal. Istirahat melompat keluar dari blok, dan melompat 'di atas' klausa lain. Jika isi klausa lain hanya mengikuti klausa untuk, itu tidak akan pernah dilompati, dan logika yang setara harus disediakan dengan meletakkannya di if. Ini telah dikatakan sebelumnya, tetapi tidak cukup dengan kata-kata ini, sehingga dapat membantu orang lain. Coba jalankan fragmen kode berikut. Saya sepenuh hati mendukung komentar 'tanpa istirahat' untuk kejelasan.
sumber
for:
/else:
, itu tidak benar-benar memberikan pembenaran untuk kata kunci yang sedangelse
. Mengingat framing yang diberikan di sini,then:
sepertinya itu akan jauh lebih alami. (Ada yang alasan untukelse
terpilih, diberikan dalam jawaban lainnya - mereka hanya tidak disediakan di sini.)Saya pikir dokumentasi memiliki penjelasan yang bagus tentang yang lain , lanjutkan
Sumber: Python 2 docs: Tutorial tentang aliran kontrol
sumber
Saya membacanya seperti:
Jika masih pada kondisi untuk menjalankan loop, melakukan hal-hal, yang lain melakukan sesuatu yang lain.
sumber
for:
/else:
membuatnya terdengar sepertielse:
akan selalu berjalan setelah loop, yang tidak terjadi.Karena bagian teknis sudah cukup banyak dijawab, komentar saya hanya terkait dengan kebingungan yang menghasilkan kata kunci daur ulang ini .
Menjadi Python bahasa pemrograman yang sangat fasih , penyalahgunaan kata kunci lebih terkenal. Kata
else
kunci tersebut dengan sempurna menggambarkan bagian dari aliran pohon keputusan, "jika Anda tidak dapat melakukan ini, (lain) lakukan itu". Itu tersirat dalam bahasa kita sendiri.Sebaliknya, menggunakan kata kunci dengan
while
danfor
pernyataan ini menciptakan kebingungan. Alasannya, karier kita sebagai programmer telah mengajarkan kita bahwaelse
pernyataan itu berada di dalam pohon keputusan; yang lingkup logis , pembungkus yang kondisional kembali jalan untuk diikuti. Sementara itu, pernyataan loop memiliki tujuan eksplisit figuratif untuk mencapai sesuatu. Sasaran ini dipenuhi setelah pengulangan proses yang berkelanjutan.if / else
menunjukkan jalan yang harus diikuti . Loop mengikuti jalur sampai "tujuan" selesai .Masalahnya adalah itu
else
adalah kata yang dengan jelas menentukan opsi terakhir dalam suatu kondisi. The semantik kata keduanya bersama oleh Python dan Bahasa Manusia. Tetapi kata lain dalam Bahasa Manusia tidak pernah digunakan untuk menunjukkan tindakan seseorang atau sesuatu akan dilakukan setelah sesuatu selesai. Ini akan digunakan jika, dalam proses menyelesaikannya, masalah muncul (lebih seperti pernyataan break ).Pada akhirnya, kata kunci akan tetap dalam Python. Sudah jelas itu adalah kesalahan, semakin jelas ketika setiap programmer mencoba untuk membuat cerita untuk memahami penggunaannya seperti beberapa perangkat mnemonik. Saya akan senang jika mereka memilih kata kunci
then
. Saya percaya bahwa kata kunci ini sangat cocok dengan aliran berulang itu, hasil setelah loop.Itu menyerupai situasi yang dimiliki beberapa anak setelah mengikuti setiap langkah dalam merakit mainan: Dan LALU apa Ayah?
sumber
Saya membacanya seperti "Ketika
iterable
habis sepenuhnya, dan eksekusi akan melanjutkan ke pernyataan berikutnya setelah menyelesaikanfor
, klausa lain akan dieksekusi." Jadi, ketika iterasi dilanggar olehbreak
, ini tidak akan dieksekusi.sumber
Saya setuju, ini lebih seperti 'elif not [kondisi (s) menaikkan istirahat]'.
Saya tahu ini adalah utas lama, tetapi saya sedang melihat pertanyaan yang sama sekarang, dan saya tidak yakin ada yang menangkap jawaban atas pertanyaan ini dengan cara yang saya pahami.
Bagi saya, ada tiga cara "membaca"
else
dalamFor... else
atauWhile... else
pernyataan, yang semuanya setara, adalah:else
==
if the loop completes normally (without a break or error)
else
==
if the loop does not encounter a break
else
==
else not (condition raising break)
(mungkin ada kondisi seperti itu, atau Anda tidak akan memiliki loop)Jadi, pada dasarnya, "lain" dalam satu lingkaran benar-benar merupakan "elif ..." di mana '...' adalah (1) tidak ada istirahat, yang setara dengan (2) BUKAN [kondisi (s) kenaikan istirahat).
Saya pikir kuncinya adalah bahwa
else
tidak ada gunanya tanpa 'istirahat', jadifor...else
termasuk:Jadi, elemen-elemen penting dari sebuah
for...else
loop adalah sebagai berikut, dan Anda akan membacanya dalam bahasa Inggris yang lebih jelas sebagai:Seperti yang dikatakan poster lainnya, jeda umumnya dinaikkan ketika Anda dapat menemukan apa yang dicari lingkaran Anda, sehingga jeda
else:
menjadi "apa yang harus dilakukan jika item target tidak ditemukan".Contoh
Anda juga dapat menggunakan penanganan eksepsi, istirahat, dan untuk loop secara bersamaan.
Hasil
Contoh
Contoh sederhana dengan istirahat dipukul.
Hasil
Contoh
Contoh sederhana di mana tidak ada istirahat, tidak ada kondisi meningkatkan istirahat, dan tidak ada kesalahan yang ditemui.
Hasil
sumber
Kata
else
kunci dapat membingungkan di sini, dan seperti yang ditunjukkan banyak orang, sesuatu sepertinobreak
,notbreak
lebih tepat.Untuk memahami
for ... else ...
secara logis, bandingkan dengantry...except...else
, tidakif...else...
, sebagian besar pemrogram python terbiasa dengan kode berikut:Demikian pula, anggap
break
sebagai jenis khususException
:Perbedaannya
python
menyiratkanexcept break
dan Anda tidak dapat menuliskannya, sehingga menjadi:Ya, saya tahu perbandingan ini bisa sulit dan melelahkan, tetapi ini memperjelas kebingungan.
sumber
Kode dalam
else
blok pernyataan akan dieksekusi ketikafor
loop tidak terputus.Dari dokumen: hancurkan dan lanjutkan Pernyataan, dan klausa lain tentang Loops
sumber
Inilah cara untuk memikirkannya yang belum pernah saya lihat orang lain sebutkan di atas:
Pertama, ingat bahwa for-loop pada dasarnya hanya gula sintaksis di sekitar while-loop. Misalnya, loop
dapat ditulis ulang (kira-kira) sebagai
Kedua, ingat bahwa while-loop pada dasarnya hanya diulangi jika-blok! Anda selalu dapat membaca while-loop sebagai "jika kondisi ini benar, jalankan tubuh, lalu kembali dan periksa lagi".
Jadi sementara / else masuk akal: Ini adalah struktur yang sama persis seperti jika / selain itu, dengan fungsi perulangan yang ditambahkan hingga kondisi menjadi salah, bukan hanya memeriksa kondisi satu kali.
Dan kemudian untuk / selain itu masuk akal juga: karena semua untuk-loop hanya gula sintaksis di atas sementara-loop, Anda hanya perlu mencari tahu apa kondisional implisit while-loop yang mendasarinya, dan kemudian sesuai dengan kapan kondisi menjadi False.
sumber
Jawaban yang bagus adalah:
Catatan saya di sini berasal dari apa yang pernah dikatakan Donald Knuth (maaf tidak dapat menemukan referensi) bahwa ada konstruk di mana sementara-yang lain tidak dapat dibedakan dari if-else, yaitu (dengan Python):
memiliki aliran yang sama (tidak termasuk perbedaan level rendah) seperti:
Intinya adalah jika-selain itu dapat dianggap sebagai gula sintaksis untuk sementara-lain yang telah tersirat
break
pada akhirif
bloknya. Implikasi sebaliknya,while
loop itu adalah ekstensiif
, lebih umum (itu hanya pemeriksaan bersyarat berulang / berulang), karenaif
sering diajarkan sebelumnyawhile
. Namun itu tidak benar karena itu berartielse
memblokir sementara-lain akan dieksekusi setiap kali ketika kondisinya salah.Untuk memudahkan pemahaman Anda, pikirkan seperti itu:
Catatan lain:
sumber
Anda bisa memikirkannya seperti,
else
seperti pada sisa barang, atau hal lainnya, yang tidak dilakukan dalam lingkaran.sumber
"lain" di sini sangat sederhana, kejam
1, "jika
for clause
sudah selesai"Adalah penting untuk menulis pernyataan panjang seperti "untuk klausa selesai", jadi mereka memperkenalkan "lain".
else
di sini adalah jika dalam sifatnya.2, Namun, Bagaimana
for clause is not run at all
Jadi pernyataan itu sepenuhnya adalah kombinasi logika:
atau begini:
atau dengan cara ini:
sumber
Berikut ini adalah kasus penggunaan khusus selain mencari. Katakanlah Anda ingin menunggu suatu kondisi menjadi benar, misalnya port terbuka pada server jauh, bersama dengan beberapa timeout. Maka Anda bisa memanfaatkan
while...else
konstruk seperti:sumber
Saya sendiri hanya mencoba untuk memahaminya. Saya menemukan bahwa berikut ini membantu!
• Pikirkan
else
sebagai berpasangan dengan bagianif
dalam loop (bukan denganfor
) - jika kondisi terpenuhi kemudian hentikan loop, kalau tidak lakukan ini - kecuali ituelse
dipasangkan dengan beberapaif
s!• Jika tidak ada
if
yang puas sama sekali, maka lakukanelse
.• Beberapa
if
s juga dapat dianggap sebagaiif
-elif
s!sumber
Saya menganggap struktur untuk (jika) A lain B, dan untuk (jika) -selain khusus jika-lain , kira-kira . Mungkin membantu untuk memahami hal lain .
A dan B dieksekusi paling banyak sekali, yang sama dengan struktur if-else.
untuk (jika) dapat dianggap sebagai khusus jika, yang melakukan loop untuk mencoba memenuhi kondisi if. Setelah kondisi if terpenuhi, A dan break ; Lain , B.
sumber
Python menggunakan yang lain setelah dan untuk loop sehingga jika tidak ada yang berlaku untuk loop, sesuatu yang lain terjadi. Sebagai contoh:
Outputnya akan menjadi 'Hai' berulang-ulang (jika saya benar).
sumber