Klausa lain pada pernyataan Python sementara

321

Saya perhatikan kode berikut legal di Python. Pertanyaan saya adalah mengapa? Apakah ada alasan khusus?

n = 5
while n != 0:
    print n
    n -= 1
else:
    print "what the..."
Ivan
sumber
5
@detly: Itu karena kebanyakan orang menghindari konstruksi ini. :) Saya percaya Guido menyebutkan selama proses Py3k bahwa, paling tidak, pilihan kata elseuntuk penggunaan ini adalah ide yang sangat buruk, dan bahwa mereka tidak akan melakukan ini lagi.
Nicholas Knight
5
@ Nicholas Knight - ya, meskipun menggoda, mungkin hanya sesuatu yang saya pahami sekilas. Setiap getah miskin lainnya harus pergi dan melihat spesifikasi bahasa, atau kembali ke masa lalu dan mengirim pertanyaan di sini di Sta- heeeeey ...
detly
8
Gagasan di balik memilih 'lain' adalah bahwa konstruksi ini seharusnya sering digunakan bersama dengan 'jika X: istirahat' di dalam while loop. Karena klausa 'else' dieksekusi jika kita tidak keluar dari loop, itu membentuk agak-agak 'lain' ke 'jika'.
Jonathan Hartley
12
Mereka harus mengganti nama itu after:.
nucky101

Jawaban:

388

The elseklausul hanya dijalankan ketika Anda whilekondisi menjadi palsu. Jika Anda breakkeluar dari loop, atau jika pengecualian muncul, itu tidak akan dieksekusi.

Salah satu cara untuk memikirkannya adalah sebagai konstruksi if / else sehubungan dengan kondisi:

if condition:
    handle_true()
else:
    handle_false()

analog dengan konstruk pengulangan:

while condition:
    handle_true()
else:
    # condition is false now, handle and go on with the rest of the program
    handle_false()

Contohnya mungkin di sepanjang baris:

while value < threshold:
    if not process_acceptable_value(value):
        # something went wrong, exit the loop; don't pass go, don't collect 200
        break
    value = update(value)
else:
    # value >= threshold; pass go, collect 200
    handle_threshold_reached()
ars
sumber
42
"Klausa lain hanya dijalankan ketika kondisi sementara Anda menjadi salah." Kata-kata di sini menyiratkan bahwa status sementara Anda berubah dari keadaan benar menjadi salah dan daripada yang lain akan dieksekusi. Namun, jika sementara tidak pernah benar, klausa lain masih akan dieksekusi.
user597608
pseudocode Jadi perbaiki saya jika saya salah, tapi ini persis sama dengan while {} something kecuali bahwa somethingakan dilewati jika Anda breakdi whileloop.
Daniel Kaplan
2
Mungkin pseudocode paling tepat adalah: while (True) {if (cond) {handle_true (); } else {handle_false (); istirahat; }}
VinGarcia
2
"jangan lulus, jangan kumpulkan 200", haha, semua orang yang tahu dari mana asalnya memiliki masa kecil yang baik
Stefan Octavian
102

The elseklausul dijalankan jika Anda keluar blok biasanya, dengan memukul kondisi loop atau jatuh dari bagian bawah blok try. Itu tidak dieksekusi jika Anda breakatau returnkeluar dari blok, atau menaikkan pengecualian. Ini berfungsi tidak hanya untuk sementara dan untuk loop, tetapi juga mencoba blok.

Anda biasanya menemukannya di tempat-tempat di mana biasanya Anda akan keluar dari loop lebih awal, dan lari dari ujung loop adalah peristiwa yang tidak terduga / tidak biasa. Misalnya, jika Anda mengulang daftar mencari nilai:

for value in values:
    if value == 5:
        print "Found it!"
        break
else:
    print "Nowhere to be found. :-("
John Kugelman
sumber
1
Sebenarnya konstruksi yang cukup berguna untuk hal seperti itu. Tidak tahu berapa kali saya meletakkannya found_it=Falsedi awal perulangan, dan kemudian melakukan pemeriksaan if pada found_itakhirnya
Cruncher
42

Sebagai balasannya Is there a specific reason?, berikut adalah satu aplikasi menarik: keluar dari beberapa level perulangan.

Inilah cara kerjanya: loop luar memiliki jeda di bagian akhir, jadi itu hanya akan dieksekusi sekali. Namun, jika loop dalam selesai (tidak menemukan pembagi), maka ia mencapai pernyataan lain dan istirahat luar tidak pernah tercapai. Dengan cara ini, pemutusan pada loop dalam akan keluar dari kedua loop, bukan hanya satu.

for k in [2, 3, 5, 7, 11, 13, 17, 25]:
    for m in range(2, 10):
        if k == m:
            continue
        print 'trying %s %% %s' % (k, m)
        if k % m == 0:
            print 'found a divisor: %d %% %d; breaking out of loop' % (k, m)
            break
    else:
        continue
    print 'breaking another level of loop'
    break
else:
    print 'no divisor could be found!'

Untuk keduanya whiledan forloop, elsepernyataan dieksekusi di akhir, kecuali breakdigunakan.

Dalam kebanyakan kasus ada cara yang lebih baik untuk melakukan ini (membungkusnya menjadi fungsi atau menaikkan pengecualian), tetapi ini berhasil!

Menandai
sumber
1
Saya tidak downvote tapi saya pikir saya tahu mengapa seseorang melakukannya. Anda tidak menjawab pertanyaan dan Anda menyediakan 14 baris kode dengan hanya 2 baris deskripsi. Jika ada relevansi dengan pertanyaan, Anda tidak memberi tahu kami ...
BlueEel
1
@BlueEel terima kasih atas umpan baliknya! Saya telah menambahkan lebih banyak penjelasan tentang kode, dan membuatnya lebih jelas bagaimana ini menjawab pertanyaan (karena memang menjawab sebagian dari itu).
Tandai
Anda berhasil meletakkan kode Anda dalam konteks dan meskipun Anda tidak menjawab semua pertanyaan, saya melihat relevansinya sekarang. Saya mengubah jawaban Anda karena sekarang berguna untuk pendatang baru dan pemula (seperti saya sendiri mengenai python). - Terima kasih, saya belajar sesuatu.
BlueEel
Saya suka aplikasi sederhana - sekarang saya mengerti mengapa seseorang mungkin menggunakannya. Meskipun saya belum pernah melihat kebutuhan untuk itu.
gabe
Contoh menunjukkan penggunaan untuk / lain tetapi pertanyaannya adalah tentang sementara / lain.
Ian Goldby
20

Klausa lain dijalankan ketika kondisi-sementara bernilai false.

Dari dokumentasi :

Pernyataan sementara digunakan untuk eksekusi berulang selama ekspresi itu benar:

while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

Ini berulang kali menguji ekspresi dan, jika itu benar, mengeksekusi suite pertama; jika ekspresi salah (yang mungkin pertama kali diuji) paket elseklausa, jika ada, dieksekusi dan loop berakhir.

Sebuah breakpernyataan dieksekusi di suite pertama berakhir loop tanpa melaksanakan elseSuite klausul ini. Sebuah continuepernyataan dieksekusi di suite pertama melompat sisa suite dan kembali ke menguji ekspresi.

Mark Rushakoff
sumber
15

Jawaban saya akan fokus pada KAPAN kita bisa menggunakan while / for-else.

Sepintas, sepertinya tidak ada yang berbeda saat menggunakan

while CONDITION:
    EXPRESSIONS
print 'ELSE'
print 'The next statement'

dan

while CONDITION:
    EXPRESSIONS
else:
    print 'ELSE'
print 'The next statement'

Karena print 'ELSE'pernyataan sepertinya selalu dieksekusi dalam kedua kasus (baik ketika whileloop selesai atau tidak berjalan).

Kemudian, itu hanya berbeda ketika pernyataan print 'ELSE'itu tidak akan dieksekusi. Itu ketika ada breakdi dalam blok kode di bawahwhile

In [17]: i = 0

In [18]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
else:
    print 'ELSE'
print 'The next statement'
   ....:
0
1
2
The next statement

Jika berbeda dengan:

In [19]: i = 0

In [20]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
print 'ELSE'
print 'The next statement'
   ....:
0
1
2
ELSE
The next statement

return tidak termasuk dalam kategori ini, karena ini memiliki efek yang sama untuk dua kasus di atas.

kenaikan gaji juga tidak menyebabkan perbedaan, karena ketika naik, di mana kode berikutnya akan dieksekusi dalam pengecualian handler (kecuali blok), kode dalam elseklausa atau tepat setelah whileklausa tidak akan dieksekusi.

HVNMencintai
sumber
4

Saya tahu ini pertanyaan lama tapi ...

Seperti yang dikatakan Raymond Hettinger, itu harus disebut while/no_breakbukan while/else.
Saya merasa mudah untuk memahami dan jika Anda melihat potongan ini.

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
if n == 0:
    print n

Sekarang alih-alih memeriksa kondisi setelah while, kita dapat menukarnya dengan elsedan menyingkirkan cek itu.

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
else:  # read it as "no_break"
    print n

Saya selalu membacanya while/no_breakuntuk memahami kode dan sintaks yang lebih masuk akal bagi saya.

Iluvatar
sumber
3

Klausa lain hanya dijalankan ketika kondisi sementara menjadi salah.

Berikut ini beberapa contohnya:

Contoh 1: Awalnya kondisinya salah, jadi klausa lain dijalankan.

i = 99999999

while i < 5:
    print(i)
    i += 1
else:
    print('this')

KELUARAN:

this

Contoh 2: Kondisi -sementara i < 5 tidak pernah menjadi salah karena i == 3memutus loop, jadi klausa lain tidak dijalankan.

i = 0

while i < 5:
    print(i)
    if i == 3:
        break
    i += 1
else:
    print('this')

KELUARAN:

0
1
2
3

Contoh 3: Kondisi -sementara i < 5 menjadi salah ketika iitu 5, jadi klausa lain dieksekusi.

i = 0

while i < 5:
    print(i)
    i += 1
else:
    print('this')

KELUARAN:

0
1
2
3
4
this
Saif Ur Rahman
sumber
0

The else:pernyataan dieksekusi jika dan hanya jika loop sementara tidak lagi memenuhi kondisinya (dalam contoh Anda, ketika n != 0palsu).

Jadi hasilnya akan seperti ini:

5
4
3
2
1
what the...
BoltClock
sumber
Saya tahu tapi ini sementara / tidak bekerja di Jawa. Saya merasa cukup menarik ketika saya tahu itu bekerja dengan Python. Saya hanya ingin tahu dan ingin tahu alasan teknisnya.
Ivan
6
@Van: Ini tidak banyak sehingga tidak berfungsi di Jawa tetapi tidak ada di Jawa. Itu bisa dibuat berfungsi, jika seseorang peduli untuk menambahkannya ke bahasa.
Ignacio Vazquez-Abrams
1
Tidak, sementara False: .. else .. masih menjalankan klausa yang lain. Lebih akurat untuk mengatakan: yang lain tidak akan berjalan jika loop terputus.
Leo Ufimtsev
0

Lain dijalankan jika loop tidak pecah.

Saya agak suka memikirkannya dengan metafora 'pelari'.

"Lain" seperti melintasi garis finish, tidak relevan apakah Anda mulai di awal atau di akhir trek. "lain" hanya tidak dieksekusi jika Anda menerobos suatu tempat di antaranya.

runner_at = 0 # or 10 makes no difference, if unlucky_sector is not 0-10
unlucky_sector = 6
while runner_at < 10:
    print("Runner at: ", runner_at)
    if runner_at == unlucky_sector:
        print("Runner fell and broke his foot. Will not reach finish.")
        break
    runner_at += 1
else:
    print("Runner has finished the race!") # Not executed if runner broke his foot.

Kasus-kasus penggunaan utama menggunakan pemecahan ini dari loop bersarang atau jika Anda ingin menjalankan beberapa pernyataan hanya jika loop tidak pecah di suatu tempat (pikirkan melanggar menjadi situasi yang tidak biasa).

Misalnya, berikut ini adalah mekanisme tentang cara keluar dari loop dalam tanpa menggunakan variabel atau mencoba / menangkap:

for i in [1,2,3]:
    for j in ['a', 'unlucky', 'c']:
        print(i, j)
        if j == 'unlucky':
            break
    else: 
        continue  # Only executed if inner loop didn't break.
    break         # This is only reached if inner loop 'breaked' out since continue didn't run. 

print("Finished")
# 1 a
# 1 b
# Finished
Leo Ufimtsev
sumber
-1

Penggunaan lebih baik dari 'while: else:' konstruksi dengan Python seharusnya jika tidak ada loop dieksekusi di 'while' maka pernyataan 'lain' dieksekusi. Cara kerjanya hari ini tidak masuk akal karena Anda dapat menggunakan kode di bawah ini dengan hasil yang sama ...

n = 5
while n != 0:
    print n
    n -= 1
print "what the..."
Jean Ferri
sumber
8
Tidak, perbedaannya adalah bahwa elseblok tidak akan dieksekusi jika Anda meninggalkan loop menggunakan breakatau returnkata kunci. Dalam contoh Anda, printakan dieksekusi juga jika loop telah berakhir pada breakperintah.
notsurewhattodo
2
Anda menggambarkan bagaimana kebanyakan orang berharap fitur itu berfungsi, bukan bagaimana sebenarnya berfungsi!
dotancohen
-2

Ini berguna untuk interaksi sosial.

while (Date != "January 1st"):
    time.sleep(1)
else:
    print("Happy new year!")
Guimoute
sumber
2
Dan apa sebenarnya tujuan dari elsesini? Kode melakukan hal yang persis sama tanpanya.
wovano
Jika jam dan kalender breakAnda selama hitung mundur, tidak menggunakan elseakan membuat Anda mengatakan "Selamat tahun baru!" langsung yang tidak masuk akal.
Guimoute
@Guimote, apa yang Anda maksud dengan "jika jam dan kalender Anda break"? Tidak ada breakdalam kode.
wovano