ข้ออื่นใน Python ในขณะที่คำสั่ง


321

ฉันสังเกตว่ารหัสต่อไปนี้ถูกกฎหมายใน Python คำถามของฉันคือทำไม มีเหตุผลที่เฉพาะเจาะจงหรือไม่?

n = 5
while n != 0:
    print n
    n -= 1
else:
    print "what the..."

5
@detly: นั่นเป็นเพราะคนส่วนใหญ่หลีกเลี่ยงการสร้างนี้ :) ฉันเชื่อว่ากุยโดพูดถึงในระหว่างกระบวนการ Py3k ว่าอย่างน้อยที่สุดการเลือกคำelseสำหรับการใช้งานนี้เป็นความคิดที่ไม่ดีอย่างน่าทึ่งและพวกเขาจะไม่ทำสิ่งเหล่านี้อีก
Nicholas Knight

5
@Nicholas Knight - ใช่แม้ว่าจะดึงดูด แต่ก็อาจเป็นสิ่งที่ฉันเข้าใจได้ทันที ทรัพย์ที่ยากจนอื่น ๆ จะต้องไปดูข้อมูลจำเพาะภาษาหรือย้อนเวลากลับไปและโพสต์คำถามที่นี่บน SteeHeeeeey ...
detly

8
แนวคิดเบื้องหลังการเลือก 'else' คือโครงสร้างนี้มักจะใช้ร่วมกับ 'if X: break' ภายในวงขณะที่ เนื่องจากประโยค 'else' ถูกเรียกใช้งานถ้าเราไม่แยกออกจากลูปมันจะสร้าง kinda-sorta 'else' เป็น 'if'
Jonathan Hartley

12
after:พวกเขาควรจะเปลี่ยนชื่อ
naught101

3
ความซ้ำซ้อนที่เป็นไปได้ของเพราะเหตุใดงูหลามจึงใช้ 'else' after for และ while loop
pirho

คำตอบ:


388

elseข้อจะถูกดำเนินการเฉพาะเมื่อคุณwhileสภาพกลายเป็นเท็จ หากคุณbreakออกจากลูปหรือหากมีการยกข้อยกเว้นมันจะไม่ถูกดำเนินการ

วิธีหนึ่งที่จะคิดเกี่ยวกับมันคือถ้า / อื่นสร้างด้วยความเคารพต่อเงื่อนไข:

if condition:
    handle_true()
else:
    handle_false()

คล้ายกับโครงสร้างลูป:

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

ตัวอย่างอาจอยู่ในแนวของ:

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()

42
"ส่วนคำสั่งอื่นจะถูกดำเนินการเฉพาะเมื่อเงื่อนไขในขณะที่คุณเป็นเท็จ" ถ้อยคำในที่นี้บอกเป็นนัยว่าขณะที่รัฐในขณะนั้นเปลี่ยนจากสถานะเป็นจริงเป็นเท็จและจะถูกประหารชีวิต อย่างไรก็ตามหากในขณะที่ไม่เคยเป็นจริงประโยคอื่นจะยังคงดำเนินการ
user597608

pseudocodeดังนั้นที่ถูกต้องฉันหากฉันผิด แต่ตรงนี้เป็นเช่นเดียวกับการwhile {} something ยกเว้นว่าsomethingจะถูกข้ามไปหากคุณbreakอยู่ในwhileวง
Daniel Kaplan

2
บางทีรหัสปลอมที่แม่นยำที่สุดอาจเป็น: ในขณะที่ (จริง) {ถ้า (cond) {handle_true (); } else {handle_false (); หยุดพัก; }}
VinGarcia

2
"อย่าผ่านไปอย่าเก็บ 200" ฮ่าฮ่าทุกคนที่รู้ว่านี่มาจากไหนในวัยเด็กที่ดี
Stefan Octavian

102

ส่วนelseคำสั่งจะถูกดำเนินการถ้าคุณออกจากบล็อกตามปกติโดยการกดปุ่มเงื่อนไขห่วงหรือล้มลงด้านล่างของลองบล็อก มันจะไม่ถูกดำเนินการถ้าคุณbreakหรือreturnออกจากบล็อกหรือยกข้อยกเว้น มันทำงานได้ไม่เพียง แต่ในขณะที่และสำหรับลูป แต่ยังลองบล็อก

โดยปกติแล้วคุณจะพบมันในสถานที่ที่โดยปกติคุณจะออกจากลูปเร็วและการวิ่งออกจากลูปนั้นเป็นโอกาสที่ไม่คาดคิด / ผิดปกติ ตัวอย่างเช่นหากคุณวนลูปผ่านรายการที่กำลังมองหาค่า:

for value in values:
    if value == 5:
        print "Found it!"
        break
else:
    print "Nowhere to be found. :-("

1
จริงๆแล้วโครงสร้างที่มีประโยชน์สำหรับสิ่งนั้น ไม่ทราบจำนวนครั้งที่ฉันได้ใส่found_it=Falseที่จุดเริ่มต้นของวงแล้วทำถ้าตรวจสอบในfound_itตอนท้าย
Cruncher

42

ในการตอบกลับIs there a specific reason?นี่คือแอปพลิเคชั่นหนึ่งที่น่าสนใจ: แบ่งออกเป็นหลายระดับ

นี่คือวิธีการทำงาน: ลูปด้านนอกมีตัวแบ่งในตอนท้ายดังนั้นมันจะถูกดำเนินการเพียงครั้งเดียว อย่างไรก็ตามหากลูปด้านในเสร็จสมบูรณ์ (ไม่พบตัวหาร) จะถึงคำสั่ง else และจะไม่ถึงตัวแบ่งด้านนอก ด้วยวิธีนี้การแตกในวงด้านในจะแยกออกจากลูปทั้งสองมากกว่าหนึ่ง

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!'

สำหรับทั้งสองwhileและforลูปelseคำสั่งจะถูกดำเนินการในตอนท้ายเว้นแต่จะbreakใช้

ในกรณีส่วนใหญ่มีวิธีที่ดีกว่าในการทำเช่นนี้ (ห่อไว้ในฟังก์ชันหรือเพิ่มข้อยกเว้น) แต่ใช้งานได้!


1
ฉันไม่ได้ลงคะแนน แต่ฉันคิดว่าฉันรู้ว่าทำไมมีคนทำ คุณไม่ได้ตอบคำถามและคุณให้รหัส 14 บรรทัดพร้อมคำอธิบายเพียง 2 บรรทัด หากมีความเกี่ยวข้องกับคำถามที่ถามว่าคุณไม่ได้บอกเรา ...
BlueEel

1
@ Blueue ขอบคุณสำหรับข้อเสนอแนะ! ฉันได้เพิ่มคำอธิบายเพิ่มเติมเกี่ยวกับรหัสและทำให้ชัดเจนขึ้นว่าจะตอบคำถามได้อย่างไร (เพราะเป็นส่วนหนึ่งของคำตอบ)
ทำเครื่องหมาย

คุณสามารถใส่รหัสของคุณในบริบทและแม้ว่าคุณจะไม่ตอบคำถามทั้งหมดที่ฉันเห็นความเกี่ยวข้องในขณะนี้ ฉันยกระดับคำตอบของคุณเนื่องจากเป็นประโยชน์สำหรับผู้มาใหม่และมือใหม่ (เช่นเดียวกับฉันในเรื่องของงูใหญ่) - ขอบคุณฉันเรียนรู้บางอย่าง
BlueEel

ฉันชอบแอปพลิเคชันที่เรียบง่าย - ตอนนี้ฉันเห็นว่าทำไมบางคนอาจใช้งาน แม้ว่าฉันไม่เคยเห็นความต้องการมัน
gabe

ตัวอย่างแสดงการใช้งานสำหรับ / else แต่คำถามนั้นเกี่ยวกับขณะ / อื่น ๆ โดยเฉพาะ
Ian Goldby

20

ประโยคอื่นถูกดำเนินการเมื่อ while-condition ประเมินเป็นเท็จ

จากเอกสาร :

คำสั่ง while ใช้สำหรับการประมวลผลซ้ำตราบใดที่นิพจน์เป็นจริง:

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

นี่เป็นการทดสอบนิพจน์ซ้ำ ๆ และถ้าเป็นจริงให้ดำเนินการชุดแรก หากการแสดงออกเป็นเท็จ (ซึ่งอาจเป็นครั้งแรกที่มีการทดสอบ) ชุดของelseข้อถ้ามีอยู่จะถูกดำเนินการและวงสิ้นสุด

breakงบดำเนินการในชุดแรกยุติวงโดยไม่ต้องดำเนินการelseชุดของประโยค continueงบดำเนินการในชุดแรกที่ข้ามส่วนที่เหลือของชุดและกลับไปทดสอบการแสดงออก


15

คำตอบของฉันจะเน้นที่เมื่อเราสามารถใช้ในขณะ / สำหรับอื่น

จากภาพรวมครั้งแรกดูเหมือนว่าจะไม่แตกต่างกันเมื่อใช้งาน

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

และ

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

เนื่องจากprint 'ELSE'คำสั่งดูเหมือนว่าจะดำเนินการเสมอในทั้งสองกรณี (ทั้งเมื่อwhileลูปเสร็จหรือไม่ทำงาน)

จากนั้นจะแตกต่างกันเมื่อคำสั่งprint 'ELSE'จะไม่ถูกดำเนินการ มันคือเมื่อมีbreakการบล็อคโค้ดอยู่ข้างใต้while

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

หากแตกต่างจาก:

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 ไม่ได้อยู่ในหมวดหมู่นี้เนื่องจากจะมีผลเหมือนกันสำหรับสองกรณีข้างต้น

การยกข้อยกเว้นยังไม่ก่อให้เกิดความแตกต่างเพราะเมื่อยกรหัสที่ถัดไปจะถูกดำเนินการอยู่ในตัวจัดการข้อยกเว้น (ยกเว้นบล็อก) รหัสในelseข้อหรือขวาหลังจากwhileข้อจะไม่ถูกดำเนินการ


4

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ ...

ขณะที่เรย์มอนด์ Hettinger กล่าวว่ามันควรจะเรียกว่าแทนwhile/no_break ฉันคิดว่ามันง่ายที่จะขีดเส้นใต้ถ้าคุณดูตัวอย่างนี้while/else

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

ตอนนี้แทนที่จะตรวจสอบเงื่อนไขหลังจากในขณะที่วนรอบเราสามารถสลับกับelseและกำจัดเช็คนั้น

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

ฉันมักจะอ่านมันwhile/no_breakเพื่อทำความเข้าใจกับรหัสและไวยากรณ์นั้นเหมาะสมสำหรับฉันมากขึ้น


3

ส่วนคำสั่งอื่นจะดำเนินการเฉพาะเมื่อในขณะที่เงื่อนไขกลายเป็นเท็จ

นี่คือตัวอย่างบางส่วน:

ตัวอย่างที่ 1:ในขั้นต้นเงื่อนไขเป็นเท็จดังนั้นคำสั่งอื่นจะถูกดำเนินการ

i = 99999999

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

เอาท์พุท:

this

ตัวอย่างที่ 2: ในขณะที่สภาพ i < 5ไม่เคยเป็นเท็จเพราะi == 3แบ่งห่วงดังนั้นข้ออื่นไม่ได้ดำเนินการ

i = 0

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

เอาท์พุท:

0
1
2
3

ตัวอย่างที่ 3: ในขณะที่สภาพ i < 5กลายเป็นเท็จเมื่อiเป็น5ดังนั้นอื่นข้อถูกประหารชีวิต

i = 0

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

เอาท์พุท:

0
1
2
3
4
this

0

else:คำสั่งจะถูกดำเนินการเมื่อใดและเฉพาะเมื่อในขณะที่วงไม่ตรงกับสภาพของ (ในตัวอย่างของคุณเมื่อn != 0เป็นเท็จ)

ดังนั้นผลลัพธ์จะเป็น:

5
4
3
2
1
what the...

ฉันรู้ แต่ในขณะนี้ / อย่างอื่นไม่สามารถใช้งานได้ใน Java ฉันพบว่ามันค่อนข้างน่าสนใจเมื่อฉันคิดว่ามันใช้งานได้ใน Python ฉันแค่อยากรู้อยากเห็นและต้องการทราบเหตุผลทางเทคนิค
Ivan

6
@Ivan: มันไม่มากนักที่ใช้งานไม่ได้กับJava แต่มันไม่มีอยู่ใน Java มันอาจจะทำให้การทำงานถ้ามีคนสนใจที่จะเพิ่มลงในภาษา
Ignacio Vazquez-Abrams

1
ไม่ในขณะที่ False: .. else .. ยังคงรันประโยคอื่นอยู่ มีความแม่นยำมากกว่าที่จะพูดว่า: มิฉะนั้นจะไม่วิ่งถ้าวนซ้ำออกไป
Leo Ufimtsev

0

ดำเนินการอื่นถ้าในขณะที่วงไม่แตก

ฉันชอบคิดด้วยคำเปรียบเทียบ 'นักวิ่ง'

"อื่น ๆ " เป็นเหมือนการข้ามเส้นชัยไม่เกี่ยวข้องกับว่าคุณเริ่มต้นที่จุดเริ่มต้นหรือจุดสิ้นสุดของแทร็ก "else" จะไม่ถูกเรียกใช้งานถ้าคุณแยกจากที่ไหน

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.

กรณีการใช้งานหลักคือการใช้การแบ่งลูปซ้อนกันหรือหากคุณต้องการเรียกใช้คำสั่งเฉพาะในกรณีที่การวนซ้ำไม่ได้อยู่ที่ใดที่หนึ่ง

ตัวอย่างเช่นต่อไปนี้เป็นกลไกในการแยกวงภายในโดยไม่ต้องใช้ตัวแปรหรือลอง / จับ:

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

-1

การใช้งาน 'while: else:' ที่ดีขึ้นใน Python ควรจะเป็นถ้าไม่มีการวนซ้ำใน 'ในขณะที่' ดังนั้นคำสั่ง 'else' จะถูกดำเนินการ วิธีการทำงานในวันนี้ไม่สมเหตุสมผลเนื่องจากคุณสามารถใช้รหัสด้านล่างด้วยผลลัพธ์เดียวกัน ...

n = 5
while n != 0:
    print n
    n -= 1
print "what the..."

8
ไม่ความแตกต่างคือelseบล็อกจะไม่ถูกดำเนินการหากคุณออกจากลูปโดยใช้คำหลักbreakหรือ returnในตัวอย่างของคุณprintจะถูกประหารชีวิตด้วยหากbreakคำสั่งวนซ้ำสิ้นสุดลง
notsurewhattodo

2
คุณอธิบายว่าคนส่วนใหญ่ต้องการให้ฟีเจอร์นี้ทำงานอย่างไรมันไม่ได้ใช้งานได้จริง!
dotancohen

-2

มันมีประโยชน์สำหรับการโต้ตอบทางสังคม

while (Date != "January 1st"):
    time.sleep(1)
else:
    print("Happy new year!")

2
และจุดประสงค์ของที่elseนี่คืออะไร? รหัสทำสิ่งเดียวกันโดยไม่ต้องมีรหัส
wovano

หากนาฬิกาและปฏิทินbreakของคุณในระหว่างการนับถอยหลังการไม่ใช้elseจะทำให้คุณพูดว่า "สวัสดีปีใหม่!" ทันทีซึ่งไม่สมเหตุสมผลใด ๆ
Guimoute

@Gimimote คุณมีความหมายอย่างไรกับ "ถ้านาฬิกาและปฏิทินของคุณbreak" ไม่มีbreakในรหัส
wovano
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.