मैं पायथन छोरों के `और` खंड को कैसे समझ सकता हूं?


191

कई पायथन प्रोग्रामर शायद इस बात से अनजान हैं कि whileलूप और forलूप के सिंटैक्स में एक वैकल्पिक else:क्लॉज शामिल है:

for val in iterable:
    do_something(val)
else:
    clean_up()

elseक्लॉज का शरीर कुछ प्रकार के सफाई-कार्यों के लिए एक अच्छी जगह है, और लूप की सामान्य समाप्ति पर निष्पादित किया जाता है: यानी, क्लॉज के साथ लूप को बाहर निकालना returnया breakछोड़ देना else; continueइसे निष्पादित करने के बाद बाहर निकलना । मैं यह जानता हूँ क्योंकि मैं सिर्फ यह देखा अप (एक बार फिर), क्योंकि मुझे याद है कभी नहीं हो सकता जबelse खंड निष्पादित किया जाता है।

हमेशा? लूप की "विफलता" पर, जैसा कि नाम से पता चलता है? नियमित समाप्ति पर? भले ही पाश के साथ बाहर निकलता है return? मैं इसे देखे बिना पूरी तरह से निश्चित नहीं हो सकता।

मैं कीवर्ड की पसंद पर अपनी निरंतर अनिश्चितता को दोषी ठहराता हूं: मुझे elseइस शब्दार्थ के लिए अविश्वसनीय रूप से असम्मानजनक लगता है । मेरा सवाल यह नहीं है कि "इस उद्देश्य के लिए इस कीवर्ड का उपयोग क्यों किया जाता है" (जो कि मैं शायद जवाब देने और टिप्पणियों को पढ़ने के बाद ही बंद करूंगा), लेकिन मैं elseकीवर्ड के बारे में कैसे सोच सकता हूं ताकि इसके शब्दार्थ समझ में आएं, और मैं इसलिए इसे याद कर सकते हैं?

मुझे यकीन है कि इस बारे में उचित मात्रा में चर्चा हुई थी, और मैं कल्पना कर सकता हूं कि tryबयान के else:खंड (जो मुझे भी देखना है) के साथ संगतता के लिए पसंद किया गया था , और लक्ष्य की सूची में नहीं जोड़ने के लक्ष्य के साथ पायथन के आरक्षित शब्द। शायद चुनने के कारणों से elseइसके कार्य को स्पष्ट किया जाएगा और इसे और अधिक यादगार बनाया जा सकता है, लेकिन मैं नाम को कार्य से जोड़ने के बाद हूं, न कि ऐतिहासिक स्पष्टीकरण के बाद।

इस प्रश्न के उत्तर , जो कि मेरा प्रश्न संक्षिप्त रूप से एक डुप्लिकेट के रूप में बंद था, में बहुत सारी दिलचस्प कहानी है। मेरे प्रश्न का एक अलग ध्यान केंद्रित है ( elseकीवर्ड विकल्प के साथ विशिष्ट शब्दार्थ को कैसे जोड़ा जाए ), लेकिन मुझे लगता है कि इस प्रश्न का लिंक कहीं न कहीं होना चाहिए।


23
कैसे के बारे में "अगर वहाँ कुछ करने के लिए छोड़ दिया है ..."
OneCricketeer

4
मुझे लगता है कि आप इस सवाल को लिखने के बाद इसे याद कर सकते हैं :)
जैस्पर

11
elseमूल रूप से इसका मतलब है, "अगर निरंतरता की स्थिति विफल हो जाती है"। लूप के लिए एक पारंपरिक में, निरंतरता की स्थिति आम तौर पर होती है i < 42, इस स्थिति में, आप उस भाग को देख सकते हैंif i < 42; execute the loop body; else; do that other thing
njzk2

1
यह सब सच है, और मुझे विशेष रूप से ड्रॉको का उत्तर पसंद है, लेकिन एक और बात पर विचार करना एक और उपलब्ध कीवर्ड है जो कुछ हद तक वाक्यविन्यास को भी अच्छा बनाता है। आप कोशिश कर सकते हैं / छोड़कर और शायद कोशिश करें / छोड़कर / अंत में, लेकिन यह और भी है - इस कोड को चलाएं अगर कोई अपवाद नहीं हुआ। जो btw है, एक ही बात के रूप में इस कोड shoving की कोशिश के तहत खंड नहीं है - अपवाद हैंडलिंग सबसे अच्छा उपयोग किया जाता है जब संकीर्ण रूप से लक्षित किया जाता है। इसलिए, जबकि यह वैचारिक अर्थ देता है - यहाँ कई उत्तरों के अनुसार - मुझे लगता है कि यह खेलने में कीवर्ड का पुन: उपयोग है - कुछ शर्तों के तहत इसे चलाएं
JL Peyret

1
@Falanwe, कोड से बाहर निकलने पर अंतर होता है break। विहित उपयोग मामला तब होता है जब लूप किसी चीज की खोज करता है, और जब वह पाता है तो टूट जाता है। कुछ न मिलने पर elseही अंजाम दिया जाता है।
एलेक्सिस

जवाबों:


212

(यह @Mark Tolonen के उत्तर से प्रेरित है।)

यदि इसकी स्थिति झूठी का मूल्यांकन करती है, तो एक ifबयान इसका elseखंड चलाता है । whileयदि इसकी स्थिति असत्य का मूल्यांकन करती है, तो सामान्यतया , एक लूप अन्य खंड को चलाता है।

यह नियम आपके द्वारा वर्णित व्यवहार से मेल खाता है:

  • सामान्य निष्पादन में, जबकि लूप बार-बार चलता है जब तक कि स्थिति झूठी का मूल्यांकन नहीं करती है, और इसलिए स्वाभाविक रूप से लूप से बाहर निकलने से बाकी खंड चलता है।
  • जब आप किसी breakकथन को निष्पादित करते हैं, तो आप स्थिति का मूल्यांकन किए बिना लूप से बाहर निकलते हैं, इसलिए स्थिति गलत का मूल्यांकन नहीं कर सकती है और आप कभी भी अन्य खंड को नहीं चलाते हैं।
  • जब आप किसी continueकथन को निष्पादित करते हैं, तो आप फिर से स्थिति का मूल्यांकन करते हैं, और ठीक वही करते हैं जो आप आमतौर पर लूप पुनरावृत्ति की शुरुआत में करते हैं। इसलिए, यदि स्थिति सही है, तो आप लूपिंग करते रहते हैं, लेकिन यदि यह गलत है तो आप अन्य क्लॉज को चलाते हैं।
  • लूप से बाहर निकलने के अन्य तरीके, जैसे return, स्थिति का मूल्यांकन नहीं करते हैं और इसलिए दूसरे खंड को नहीं चलाते हैं।

forलूप उसी तरह व्यवहार करते हैं। यदि कंडक्टर के पास अधिक तत्व हैं, या अन्यथा अन्यथा, स्थिति को सही मानें।


8
यह सबसे उत्कृष्ट उत्तर है। अपने छोरों को एलीफ बयानों की एक श्रृंखला की तरह व्यवहार करें और अन्य व्यवहार इसके प्राकृतिक तर्क को उजागर करेंगे।
नॉमिनेटर

1
मुझे यह उत्तर पसंद है, लेकिन यह elifबयानों की एक श्रृंखला के साथ एक सादृश्य नहीं खींच रहा है । वहाँ एक जवाब है कि करता है, और यह एक शुद्ध upvote है।
एलेक्सिस

2
ठीक नहीं, कुछ समय पहले लूप की स्थिति ठीक होने से पहले गलत हो सकती है break, जिस स्थिति में elseयह नहीं चलेगा लेकिन स्थिति गलत है। इसी तरह forछोरों के साथ यह breakअंतिम तत्व पर हो सकता है ।
तदह मैकडॉनल्ड्स-जेनसेन

36

इसे इस तरह से सोचना बेहतर है: elseब्लॉक को हमेशा निष्पादित किया जाएगा यदि पूर्ववर्ती ब्लॉक में सब कुछ ठीक हो जाता है forजैसे कि यह थकावट तक पहुंचता है।

इस संदर्भ में अधिकार का अर्थ होगा exception, नहीं break, नहीं, नहीं return। हाइजैक नियंत्रण से किसी भी बयान के forकारण elseब्लॉक को बायपास किया जाएगा।


किसी वस्तु के लिए खोज करते समय एक सामान्य उपयोग का मामला पाया जाता है iterable, जिसके लिए खोज को तब बुलाया जाता है जब आइटम पाया जाता है या एक "not found"झंडा उठाया जाता है / निम्नलिखित elseब्लॉक के माध्यम से मुद्रित किया जाता है :

for items in basket:
    if isinstance(item, Egg):
        break
else:
    print("No eggs in basket")  

A continueनियंत्रण से अपहरण नहीं करता है for, इसलिए नियंत्रण समाप्त elseहोने के बाद आगे बढ़ेगा for


20
ध्वनि बहुत अच्छा है ... लेकिन फिर तुम उम्मीद थी एक elseखंड निष्पादित करने के लिए चीजों को जब नहीं है , है ना जाना होगा ना? मैं पहले से ही उलझन में हूँ ...
एलेक्सिस

मुझे आपसे "तकनीकी रूप से, यह [प्रत्येक elseशब्द के समान शब्दशः ] समान नहीं है" से असहमत होना पड़ता है , क्योंकि elseजब मुझे पाश का मूल्यांकन करने के लिए शर्तों में से कोई भी सही नहीं है , तब तक चलाया जाता है, जैसा कि मैं अपने उत्तर
टैडग मैकडॉनल्ड जेन्सन

@ तदहग्मकडोनाल्ड-जेनसेन आप एक पर लूप को तोड़ सकते हैं False। तो कैसे टूट गया forहै का प्रश्न उपयोग के मामले पर निर्भर करता है।
मोशे कोल्डोय

यह सही है, मैं किसी और तरीके से "कुछ और" (जो वास्तव elseमें अजगर के अन्य उपयोगों में परिलक्षित होता है) का अंग्रेजी अर्थ क्या होता है, से संबंधित है । आप जो कुछ भी करते हैं else, @Moses का एक अच्छा सहज सारांश प्रदान करते हैं , लेकिन यह नहीं कि हम इस व्यवहार को "और" के साथ कैसे जोड़ सकते हैं। यदि एक अलग कीवर्ड का उपयोग किया गया था (उदाहरण के लिए, संबंधित प्रश्न के इस उत्तरnobreak में ), तो समझ में आना आसान होगा।
एलेक्सिस

1
इसका वास्तव में "सही चल रही चीजों" से कोई लेना-देना नहीं है। अन्य को विशुद्ध रूप से निष्पादित किया जाता है जब if/ whileस्थिति झूठी का मूल्यांकन करती है या forवस्तुओं से बाहर होती है। breakयुक्त लूप मौजूद है (के बाद else)। continueवापस जाता है और लूप स्थिति का फिर से मूल्यांकन करता है।
टॉन्सन

31

एक ifनिष्पादन कब होता है else? जब इसकी हालत झूठी है। यह while/ के लिए समान है else। तो आप सोच सकते हैं while/ elseसिर्फ एक के रूप में ifअपने असली हालत चल रहता है कि जब तक यह गलत मूल्यांकन करता है। A breakवह नहीं बदलता है। यह सिर्फ मूल्यांकन के बिना युक्त लूप से बाहर कूदता है। elseकेवल निष्पादित करता है, तो है का मूल्यांकनif / whileहालत झूठी है।

forसिवाय इसके झूठी हालत अपने इटरेटर थकाऊ है, इसी तरह की है।

continueऔर breakनिष्पादित नहीं करते else। यह उनका कार्य नहीं है। breakयुक्त पाश बाहर निकालता है। continueयुक्त पाश, जहां पाश हालत मूल्यांकन किया जाता है के शीर्ष करने के लिए वापस चला जाता है। यह मूल्यांकन if/ whileझूठे (या forकोई और आइटम नहीं) का कार्य है जो निष्पादित करता है elseऔर कोई अन्य तरीका नहीं है।


1
आप जो कहते हैं वह बहुत ही समझदार लगता है, लेकिन तीन टर्मिनेशन शर्तों को एक साथ लूपिंग करना, "जब तक [स्थिति] गलत है या टूटती है / जारी रहती है", गलत है: elseयदि लूप के साथ continue(या सामान्य रूप से) बाहर निकाला जाता है, तो भी, क्लॉज को निष्पादित किया जाता है , लेकिन नहीं अगर हम साथ बाहर निकलें break। ये सूक्ष्मताएँ इसीलिए हैं कि मैं वास्तव में elseयह जानने की कोशिश कर रहा हूँ कि क्या पकड़ता है और क्या नहीं।
एलेक्सिस

4
@alexis हाँ मुझे वहाँ स्पष्ट करने की आवश्यकता थी। संपादित। जारी रखना अन्य को निष्पादित नहीं करता है, लेकिन लूप के शीर्ष पर वापस लौटता है जो तब झूठ का मूल्यांकन कर सकता है।
मार्क टॉलेनन

24

यह अनिवार्य रूप से इसका मतलब है:

for/while ...:
    if ...:
        break
if there was a break:
    pass
else:
    ...

यह इस सामान्य पैटर्न के लेखन का एक अच्छा तरीका है:

found = False
for/while ...:
    if ...:
        found = True
        break
if not found:
    ...

elseखंड एक है अगर वहाँ निष्पादित नहीं किया जाएगा returnक्योंकि returnपत्ते समारोह, के रूप में यह करने के लिए है। इसका एकमात्र अपवाद जो आप सोच रहे होंगे finally, जिसका उद्देश्य यह सुनिश्चित करना है कि इसे हमेशा निष्पादित किया जाए।

continueइस मामले से कोई खास लेना देना नहीं है। यह लूप की वर्तमान पुनरावृत्ति का कारण बनता है जो पूरे लूप को समाप्त करने के लिए हो सकता है, और स्पष्ट रूप से उस मामले में लूप द्वारा समाप्त नहीं किया गया था break

try/else समान है:

try:
    ...
except:
    ...
if there was an exception:
    pass
else:
    ...

20

यदि आप अपने छोरों को इस तरह की संरचना के रूप में समझते हैं (कुछ छद्म कोड):

loop:
if condition then

   ... //execute body
   goto loop
else
   ...

यह थोड़ा अधिक समझ में आ सकता है। एक लूप अनिवार्य रूप से केवल एक ifबयान है जो स्थिति होने तक दोहराया जाता है false। और यह महत्वपूर्ण बिंदु है। लूप इसकी स्थिति की जांच करता है और देखता है कि यह falseइस प्रकार निष्पादित होता है else(सामान्य की तरह if/else) और फिर लूप किया जाता है।

तो ध्यान दें कि else हालत की जाँच होने पर एकमात्र निष्पादित हो जाता है । इसका मतलब है कि यदि आप उदाहरण के लिए returnया क के साथ निष्पादन के बीच में लूप के शरीर से बाहर निकलते हैं break, क्योंकि स्थिति की फिर से जाँच नहीं की जाती है, तो elseमामले का निष्पादन नहीं किया जाएगा।

continueदूसरी ओर ए वर्तमान निष्पादन को रोकता है और फिर लूप की स्थिति की फिर से जांच करने के लिए वापस कूदता है, यही कारण है कि elseइस परिदृश्य में पहुंचा जा सकता है।


मुझे यह उत्तर बहुत पसंद है, लेकिन आप इसे सरल कर सकते हैं: endलेबल को छोड़ें और शरीर के goto loopअंदर डालें if। हो सकता है कि ifलेबल की तरह एक ही लाइन पर रखने से भी अतिरिक्त हो , और यह अचानक ओरिगनल की तरह दिखे।
बरगी

@Bergi हाँ, मुझे लगता है कि यह थोड़ा स्पष्ट करता है, धन्यवाद।
केयवन

15

लूप के elseक्लॉज के साथ मेरा गेटा मोमेंट तब था जब मैं रेमंड हेटिंगर की एक बात देख रहा था , जिसने इस बारे में एक कहानी बताई थी कि उसे कैसे लगा कि उसे बुलाया जाना चाहिए था nobreak। निम्नलिखित कोड पर एक नज़र डालें, आपको क्या लगता है कि यह क्या करेगा?

for i in range(10):
    if test(i):
        break
    # ... work with i
nobreak:
    print('Loop completed')

आप क्या अनुमान लगा सकते हैं? ठीक है, जो कहता है कि भाग nobreakकेवल तभी निष्पादित किया जाएगा जब एक breakबयान लूप में हिट नहीं किया गया था।


8

आमतौर पर मैं इस तरह एक लूप संरचना के बारे में सोचता हूं:

for item in my_sequence:
    if logic(item):
        do_something(item)
        break

वेरिएबल नंबर की तरह बहुत कुछ होना if/elif:

if logic(my_seq[0]):
    do_something(my_seq[0])
elif logic(my_seq[1]):
    do_something(my_seq[1])
elif logic(my_seq[2]):
    do_something(my_seq[2])
....
elif logic(my_seq[-1]):
    do_something(my_seq[-1])

इस मामले में elseलूप के लिए elseस्टेटमेंट ठीक उसी तरह से काम करता है जैसे कि elifs की चेन पर स्टेटमेंट होता है , यह केवल तभी निष्पादित होता है जब कोई भी ट्रू के मूल्यांकन से पहले की कोई भी स्थिति न हो। (या returnएक अपवाद के साथ निष्पादन को तोड़ दें ) यदि मेरा लूप इस विनिर्देश के लायक नहीं है, तो आमतौर पर मैं for: elseइस प्रश्न को पोस्ट करने वाले सटीक कारण का उपयोग करने का विकल्प चुनता हूं : यह गैर-सहज है।


सही। लेकिन एक लूप कई बार चलता है, इसलिए यह थोड़ा अस्पष्ट है कि आप इसे फॉर-लूप के लिए कैसे लागू करते हैं। क्या आप स्पष्ट कर सकते हो?
एलेक्सिस

@alexis मैंने अपना उत्तर पुनः प्राप्त कर लिया है, मुझे लगता है कि यह अब बहुत स्पष्ट है।
तदह मैकडॉनल्ड्स-जेनसन

7

दूसरों ने पहले से ही यांत्रिकी के बारे में समझाया है while/for...else, और पायथन 3 भाषा के संदर्भ में आधिकारिक परिभाषा (देखें जबकि और इसके लिए ) है, लेकिन यहां मेरा व्यक्तिगत एमएनओनिक, एफडब्ल्यूआईडब्ल्यू है। मुझे लगता है कि मेरे लिए यह कुंजी दो भागों में टूट गई है: एक का अर्थ समझने के लिएelse लूप सशर्त के संबंध में , और एक लूप नियंत्रण को समझने के लिए।

मुझे समझ से शुरू करना आसान लगता है while...else:

whileआपके पास अधिक आइटम हैं, सामान रखें, elseयदि आप बाहर भागते हैं, तो ऐसा करें

for...elseस्मरक मूलतः एक ही है:

forहर आइटम, सामान करें, लेकिन elseअगर आप बाहर भागते हैं, तो ऐसा करें

दोनों ही मामलों में, यह elseहिस्सा केवल एक बार पहुंचता है जब प्रक्रिया के लिए अधिक आइटम नहीं होते हैं, और अंतिम आइटम को एक नियमित तरीके से संसाधित किया जाता है (अर्थात नहीं breakया नहीं return)। एक continueबस वापस जाता है और देखता है कि क्या कोई और आइटम हैं। इन नियमों के लिए मेरी स्मृति दोनों पर लागू होती है whileऔर for:

जब breakआईएनजी या returnआईएनजी, कुछ elseकरना नहीं है,
और जब मैं कहता हूं continue, तो यह आपके लिए "लूप बैक टू स्टार्ट" है

- "लूप बैक टू स्टार्ट" का अर्थ है, जाहिर है, लूप की शुरुआत जहां हम जांचते हैं कि क्या पुनरावृत्ति में कोई और आइटम हैं, जहां तक elseइसका संबंध है, continueवास्तव में बिल्कुल कोई भूमिका नहीं निभाता है।


4
मेरा सुझाव है कि इसे यह कहकर बढ़ाया जा सकता है कि जब तक आप जो खोज रहे हैं उसे रोकना चाहते हैं , या आप आइटम से बाहर भागना चाहते हैं , तब तक के लिए / अन्यथा लूप का सामान्य उद्देश्य वस्तुओं की जांच करना है । "और" आइटम से बाहर चलाने के लिए मौजूद है (आप जो खोज रहे थे, उसे पाए बिना)।
सुपरकैट

@ सुपरकैट: हो सकता है, लेकिन मुझे नहीं पता कि सबसे आम उपयोग क्या हैं। elseभी कुछ जब आप बस सभी आइटम को पूर्ण कर लें करने के लिए इस्तेमाल किया जा सकता। उदाहरणों में एक लॉग प्रविष्टि लिखना, एक यूजर इंटरफेस को अपडेट करना, या कुछ अन्य प्रक्रिया को इंगित करना शामिल है जो आप कर रहे हैं। सच में कुछ भी। इसके अलावा, कोड के कुछ टुकड़ों में breakलूप के अंदर "सफल" केस अंत होता है , और elseइसका उपयोग "एरर" केस को संभालने के लिए किया जाता है, जहां आपको पुनरावृत्ति के दौरान कोई उपयुक्त वस्तु नहीं मिली (शायद यही आप सोच रहे थे का?)।
फाबियान फागेरहोम

1
मैं जिस केस के बारे में सोच रहा था, वह ठीक यही था कि सफल मामला "ब्रेक" के साथ समाप्त होता है, और "बाकी" सफलता की कमी को संभालता है। यदि लूप के भीतर कोई "ब्रेक" नहीं है, तो "बाकी" कोड एन्कोडिंग ब्लॉक के हिस्से के रूप में लूप का अनुसरण कर सकता है।
17

जब तक आपको उस मामले के बीच अंतर करने की आवश्यकता नहीं है जहां लूप बिना किसी रुकावट (और वह एक सफल मामला था) और उस मामले में जहां यह नहीं था, सभी पुनरावृत्त वस्तुओं से गुजरा। फिर आपको लूप के elseब्लॉक में "फाइनल" कोड डालना होगा , या अन्य साधनों का उपयोग करके परिणाम का ट्रैक रखना होगा। मैं मूल रूप से सहमत हूं, मैं सिर्फ यह कह रहा हूं कि मुझे नहीं पता कि लोग इस सुविधा का उपयोग कैसे करते हैं और इसलिए मैं यह मानने से बचना चाहूंगा कि " elseसफल मामला संभालता है" परिदृश्य या " elseअसफल मामले को संभालता है" परिदृश्य अधिक सामान्य है। लेकिन आपके पास एक अच्छा बिंदु है, इसलिए टिप्पणी करें!
फेबियान फागिरहोम

7

में टेस्ट चालित विकास (TDD), का उपयोग करते समय परिवर्तन प्राथमिकता परिसर प्रतिमान, आप सशर्त बयान का सामान्यीकरण के रूप में छोरों का इलाज।

यह दृष्टिकोण इस वाक्यविन्यास के साथ अच्छी तरह से जोड़ता है, यदि आप केवल सरल if/else(नहीं elif) कथनों पर विचार करते हैं:

if cond:
    # 1
else:
    # 2

इसे सामान्य करता है:

while cond:  # <-- generalization
    # 1
else:
    # 2

अच्छी तरह से।

अन्य भाषाओं में, संग्रह के साथ मामलों के लिए एक ही मामले से टीडीडी के कदमों को और अधिक रिफैक्टिंग की आवश्यकता होती है।


यहाँ 8 वें ब्लॉग से एक उदाहरण दिया गया है :

8 वें ब्लॉग पर लिंक किए गए लेख में, वर्ड लपेट काटा पर विचार किया गया है: स्ट्रिंग्स ( sनीचे स्निपेट्स में चर) को जोड़ने के लिए लाइन ब्रेक को जोड़ने के लिए उन्हें एक दिए गए चौड़ाई (नीचे स्निपेट में चर) फिट करने के लिए length। एक बिंदु पर कार्यान्वयन इस प्रकार दिखता है (जावा):

String result = "";
if (s.length() > length) {
    result = s.substring(0, length) + "\n" + s.substring(length);
} else {
    result = s;
}
return result;

और अगला परीक्षण, जो वर्तमान में विफल है:

@Test
public void WordLongerThanTwiceLengthShouldBreakTwice() throws Exception {
    assertThat(wrap("verylongword", 4), is("very\nlong\nword"));
    }

तो हमारे पास कोड है जो सशर्त रूप से काम करता है: जब कोई विशेष स्थिति पूरी होती है, तो एक लाइन ब्रेक जोड़ा जाता है। हम कई लाइन ब्रेक को संभालने के लिए कोड को बेहतर बनाना चाहते हैं। लेख में प्रस्तुत समाधान, (यदि-> जबकि) परिवर्तन लागू करने का प्रस्ताव करता है , हालांकि लेखक एक टिप्पणी करता है कि:

जबकि छोरों में क्लॉस नहीं हो सकता है else, इसलिए हमें elseपथ में कम करके पथ को समाप्त करने की आवश्यकता है if। फिर, यह एक refactoring है।

जो एक असफल परीक्षण के संदर्भ में कोड में अधिक परिवर्तन करने के लिए मजबूर करता है:

String result = "";
while (s.length() > length) {
    result += s.substring(0, length) + "\n";
    s = s.substring(length);
}
result += s;

टीडीडी में हम टेस्ट पास करने के लिए यथासंभव कम कोड लिखना चाहते हैं। पायथन के सिंटैक्स के लिए निम्नलिखित परिवर्तन संभव है:

से:

result = ""
if len(s) > length:
    result = s[0:length] + "\n"
    s = s[length:]
else:
    result += s

सेवा:

result = ""
while len(s) > length:
    result += s[0:length] + "\n"
    s = s[length:]
else:
    result += s

6

जिस तरह मै इसे देखता हूँ, else: जब आप लूप के अंत में पुनरावृति करते हैं तो आग लग जाती है।

यदि आप breakया returnया raiseआप पुनरावृति पाश के अंत अतीत नहीं करते हैं, आप immeadiately रोक, और इस तरह else:ब्लॉक नहीं चलेंगे। यदि आप continueअभी भी लूप के अंत में पुनरावृति करते हैं, क्योंकि अगले पुनरावृत्ति के लिए बस जारी है। यह लूप बंद नहीं करता है।


1
मुझे ऐसा लगता है, मुझे लगता है कि आप कुछ करने के लिए हैं। यह लूप कीवर्ड के पहले बुरे दिनों में लागू किए जाने वाले लूपिंग के साथ थोड़े से संबंध रखता है। (अर्थात्: चेक को लूप के निचले भाग में रखा गया था , gotoसफलता के शीर्ष के साथ ।) लेकिन यह शीर्ष-मतदान जवाब का एक छोटा संस्करण है ...
एलेक्सिस

@alexis, व्यक्तिपरक, लेकिन मुझे इसके बारे में सोचना आसान व्यक्त करने का मेरा तरीका लगता है।
विंस्टन इवर्ट

वास्तव में मैं सहमत हूँ। यदि केवल इसलिए कि यह पिथियर है।
एलेक्सिस

4

elseलूप निर्माण का हिस्सा होने के कारण खंड के बारे में सोचो ; breakलूप से पूरी तरह से टूट जाता है, और इस तरह elseक्लॉज को छोड़ देता है।

लेकिन वास्तव में, मेरी मानसिक मानचित्रण केवल यह है कि यह पैटर्न C / C ++ पैटर्न का 'संरचित' संस्करण है:

  for (...) {
    ...
    if (test) { goto done; }
    ...
  }
  ...
done:
  ...

इसलिए जब मैं इसका सामना for...elseकरता हूं या इसे सीधे लिखता हूं, तो इसे सीधे समझने के बजाय , मैं इसे मानसिक रूप से पैटर्न की उपरोक्त समझ में तब्दील करता हूं और फिर वर्कऑन सिंटैक्स मैप के किन हिस्सों के पैटर्न के किन हिस्सों में काम करता हूं।

(मैंने 'संरचित' को डराने वाले उद्धरणों में रखा क्योंकि अंतर यह नहीं है कि कोड संरचित या असंरचित है, लेकिन केवल यह है कि क्या कीवर्ड और व्याकरण विशेष संरचना के लिए समर्पित हैं)


1
कहाँ है else? यदि आपके पास done:लेबल का मतलब प्रॉक्सी को खड़ा करना है या else:, मेरा मानना ​​है कि आपके पास यह बिल्कुल पीछे की तरफ है।
एलेक्सिस

@alexis 'शेष' कोड में भरने होगा '...' से ठीक पहलेdone: लेबल। समग्र पत्राचार, हो सकता है, इस प्रकार, सबसे अच्छा कहा गया है: पायथन में else-ऑन-लूप निर्माण है ताकि आप इस नियंत्रण प्रवाह पैटर्न को बिना व्यक्त कर सकें goto
16

इस नियंत्रण प्रवाह पैटर्न को निष्पादित करने के अन्य तरीके हैं, उदाहरण के लिए एक ध्वज सेट करके। वही elseबचता है।
एलेक्सिस

2

यदि आप के elseसाथ जोड़ी for, यह भ्रामक हो सकता है। मुझे नहीं लगता कि elseइस सिंटैक्स के लिए कीवर्ड एक बढ़िया विकल्प था, लेकिन अगर आप इसके elseसाथ ifजोड़ते हैं break, तो आप देख सकते हैं कि यह वास्तव में समझ में आता है। elseपूर्ववर्ती नहीं होने पर बमुश्किल उपयोगी हैif कथन हूं और मेरा मानना ​​है कि इस कारण वाक्य रचना डिजाइनर ने कीवर्ड को चुना।

मैं इसे मानव भाषा में प्रदर्शित करता हूं।

forसंदिग्ध व्यक्ति के समूह में प्रत्येक व्यक्ति ifआपराधिक breakजांच है। elseरिपोर्ट विफलता।


1

जिस तरह से मैं इसके बारे में सोचता हूं, कुंजी continueइसके बजाय अर्थ पर विचार करना हैelse

आपके द्वारा उल्लिखित अन्य कीवर्ड लूप से बाहर निकलने (असामान्य रूप से बाहर निकलने) का उल्लेख करते हैं continue यह लूप के अंदर कोड ब्लॉक के शेष भाग को नहीं छोड़ता है। तथ्य यह है कि यह लूप समाप्ति से पहले हो सकता है आकस्मिक है: लूप सशर्त अभिव्यक्ति का मूल्यांकन करके समाप्ति वास्तव में सामान्य तरीके से की जाती है।

फिर आपको बस यह याद रखने की जरूरत है कि elseक्लॉज को सामान्य लूप समाप्ति के बाद निष्पादित किया जाता है।


0
# tested in Python 3.6.4
def buy_fruit(fruits):
    '''I translate the 'else' below into 'if no break' from for loop '''
    for fruit in fruits:
        if 'rotten' in fruit:
            print(f'do not want to buy {fruit}')
            break
    else:  #if no break
        print(f'ready to buy {fruits}')


if __name__ == '__main__':
    a_bag_of_apples = ['golden delicious', 'honeycrisp', 'rotten mcintosh']
    b_bag_of_apples = ['granny smith', 'red delicious', 'honeycrisp', 'gala', 'fuji']
    buy_fruit(a_bag_of_apples)
    buy_fruit(b_bag_of_apples)

'''
do not want to buy rotten mcintosh
ready to buy ['granny smith', 'red delicious', 'honeycrisp', 'gala', 'fuji']
'''
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.