Skip to content
This page has been auto-translated and may contain errors.View in English

नियंत्रण प्रवाह

अब तक आपने जो भी प्रोग्राम लिखे हैं, वे हर बार उसी तरह चलते हैं: ऊपर से नीचे, एक समय में एक लाइन। यह सरल स्क्रिप्ट के लिए काम करता है, लेकिन वास्तविक प्रोग्रामों को निर्णय लेने और काम दोहराने की आवश्यकता होती है। एक क्विज़ को जाँचना होता है कि उत्तर सही है या नहीं। एक गेम को तब तक चलते रहना चाहिए जब तक खिलाड़ी जीत या हार नहीं जाता। यह अध्याय बताता है कि आप अपने प्रोग्राम को कैसे शाखाबद्ध और दोहरा सकते हैं।

नियंत्रण प्रवाह आपके प्रोग्राम के निष्पादन पथ को आकार देता है। शर्तें (if/elif/else) शाखाओं के बीच चयन करती हैं। लूप (while, for) ब्लॉक दोहराते हैं। Python का for लूप एक इटरेटर प्रोटोकॉल है, न कि इंडेक्स-आधारित काउंटर। सिंटैक्स और अंतर्निहित मॉडल दोनों को समझने से आपका कोड साफ़ बनता है।

Python के नियंत्रण प्रवाह primitives हैं if/elif/else, while, और forfor iterable पर __iter__ को आह्वान करता है और StopIteration तक next() कॉल करता है। while एक शर्त ऑब्जेक्ट का मूल्यांकन __bool__ या __len__ के माध्यम से करता है। break और continue निकटतम संलग्न लूप को प्रभावित करते हैं; loop-else तभी चलता है जब लूप break के बिना समाप्त हो जाए।

तुलनाएँ

निर्णय लेने से पहले, आपको चीजों की तुलना करनी होती है। तुलना ऑपरेटर True या False लौटाते हैं। शुरुआत में सही करने के लिए सबसे महत्वपूर्ण: = एक मान को असाइन करता है, == जाँचता है कि दो मान बराबर हैं या नहीं। इन्हें मिलाना शुरुआती लोगों की सबसे आम गलतियों में से एक है।

तुलना ऑपरेटर संबंधित डंडर मेथड्स (__eq__, __lt__, आदि) को कॉल करते हैं और एक bool लौटाते हैं। Python चेन की गई तुलनाओं का समर्थन करता है: 0 < x < 10 का मूल्यांकन 0 < x and x < 10 के रूप में किया जाता है, न कि अधिकांश भाषाओं की तरह बाएँ से दाएँ। स्ट्रिंग तुलना लेक्सिकोग्राफिक होती है, जो Unicode कोड पॉइंट पर आधारित होती है।

तुलना ऑपरेटर रिच कम्पेरिज़न मेथड्स कॉल करते हैं: __eq__, __ne__, __lt__, __le__, __gt__, __ge__। Python चेन की गई तुलनाओं का समर्थन करता है जो शॉर्ट-सर्किट होती हैं: a < b < c बन जाता है a < b and b < c, लेकिन b का मूल्यांकन केवल एक बार होता है। is ऑब्जेक्ट पहचान (id() समानता) की जाँच करता है, मान समानता की नहीं; मान तुलनाओं के लिए == का उपयोग करें और is का उपयोग केवल None, True, False के लिए करें।

python
5 > 3     # True
5 < 3     # False
5 == 5    # True   (ध्यान दें: डबल equals; = असाइनमेंट है, == तुलना है)
5 != 3    # True   ("बराबर नहीं है")
5 >= 5    # True   ("इससे बड़ा या बराबर")
5 <= 4    # False  ("इससे छोटा या बराबर")

= बनाम == का अंतर लगभग सभी को शुरुआत में परेशान करता है। असाइनमेंट (=) एक मान संग्रहीत करता है; तुलना (==) जाँचती है कि दो मान समान हैं या नहीं।

आप स्ट्रिंग्स की भी तुलना कर सकते हैं। Python उन्हें वर्णानुक्रम में तुलना करता है:

python
"apple" == "apple"   # True
"apple" < "banana"   # True  (a, b से पहले आता है)
"apple" == "Apple"   # False (केस-सेंसिटिव)

शर्तों को संयोजित करना

and, or, और not तुलनाओं को संयोजित करते हैं। and के लिए दोनों पक्षों का सत्य होना आवश्यक है। or के लिए कम से कम एक पक्ष की आवश्यकता होती है। not परिणाम को पलट देता है। ये आपको वास्तविक दुनिया की शर्तें व्यक्त करने देते हैं जैसे "स्कोर पास हो रहा है AND उपयोगकर्ता सक्रिय है"।

and और or शॉर्ट-सर्किट करते हैं: and पहले falsy ऑपरेंड पर रुकता है, or पहले truthy पर रुकता है। वे वास्तविक ऑपरेंड मान लौटाते हैं, केवल True या False नहीं। not ऑपरेंड पर __bool__ कॉल करता है और उलटा परिणाम लौटाता है।

and बाएँ से दाएँ मूल्यांकन करता है और पहला falsy ऑपरेंड लौटाता है, या यदि सभी truthy हैं तो अंतिम ऑपरेंड। or पहला truthy ऑपरेंड लौटाता है, या यदि सभी falsy हैं तो अंतिम। यह शॉर्ट-सर्किट व्यवहार एक गारंटी है: यदि बायाँ पक्ष परिणाम निर्धारित करता है तो दायाँ पक्ष मूल्यांकित नहीं होता। not x True if not bool(x) else False के बराबर है, लेकिन Python इसे ऑप्टिमाइज़ करता है।

python
age   = 25
score = 88

age >= 18 and score >= 80    # True  (दोनों सत्य होने चाहिए)
age < 18 or score >= 80      # True  (कम से कम एक सत्य होना चाहिए)
not age >= 18                # False (परिणाम पलटता है)

and के लिए दोनों पक्षों की आवश्यकता होती है। or के लिए कम से कम एक पक्ष की आवश्यकता होती है। not उलटा करता है।

Truthy और falsy

Python में हर मान की एक बूलियन व्याख्या होती है, भले ही वह True या False न हो। खाली स्ट्रिंग, शून्य, खाली सूचियाँ, और None एक शर्त में False की तरह व्यवहार करते हैं। बाकी सब कुछ True की तरह व्यवहार करता है। इसका मतलब है कि if results: यह जाँचता है कि सूची खाली नहीं है, बिना if len(results) > 0: लिखे।

Python के truthiness नियम: falsy मान हैं False, 0, 0.0, "", [], (), {}, set(), और None। बाकी सब truthy है। शर्तें ऑब्जेक्ट पर __bool__ कॉल करती हैं, यदि __bool__ परिभाषित नहीं है तो __len__ पर फ़ॉलबैक करती हैं। शून्य-लंबाई वाले __len__ के साथ एक ऑब्जेक्ट falsy होता है।

ट्रुथ टेस्टिंग __bool__ कॉल करती है। यदि __bool__ परिभाषित नहीं है, तो Python __len__ पर फ़ॉलबैक करता है: __len__ == 0 वाला ऑब्जेक्ट falsy होता है। कस्टम क्लासेस दोनों में से किसी एक मेथड को लागू करके truthiness को नियंत्रित करती हैं। मानक falsy मान हैं: False, 0, 0.0, 0j, "", b"", [], (), {}, set(), frozenset(), None, और कोई भी ऑब्जेक्ट जिसका __bool__ False लौटाता है या __len__ 0 लौटाता है।

python
# ये सभी एक शर्त में False की तरह व्यवहार करते हैं:
False, 0, 0.0, "", [], {}, (), None

# बाकी सब कुछ True की तरह व्यवहार करता है

इसका मतलब है कि if results: "यदि सूची खाली नहीं है" कहने का एक स्वाभाविक तरीका है, और if name: जाँचता है कि स्ट्रिंग में कोई सामग्री है या नहीं।

if / elif / else

if स्टेटमेंट कोड के एक ब्लॉक को केवल तभी चलाता है जब इसकी शर्त True हो। elif और शर्तें जोड़ता है यदि पहली false थी। else उन सभी को पकड़ता है जो किसी भी शर्त से मेल नहीं खाते। Python ब्रेसेस के बजाय इंडेंटेशन का उपयोग करता है यह परिभाषित करने के लिए कि प्रत्येक ब्लॉक के अंदर क्या है।

if/elif/else शर्तों का मूल्यांकन ऊपर से नीचे करता है और पहले मेल खाने वाले ब्लॉक को चलाता है। Python ब्लॉक स्कोप परिभाषित करने के लिए इंडेंटेशन (परंपरागत रूप से 4 स्पेस) का उपयोग करता है; असंगत इंडेंटेशन एक SyntaxError है। केवल एक शाखा चलती है: एक बार शर्त मेल खाने पर, सभी बाद के elif और else को छोड़ दिया जाता है।

Python ब्लॉक डिलिमिटर के रूप में इंडेंटेशन का उपयोग करता है, जिसे पार्सर द्वारा प्रवर्तित किया जाता है। इंटरप्रेटर प्रत्येक शाखा के लिए SETUP_BLOCK बाइटकोड उत्पन्न करता है; बिल्कुल एक शाखा निष्पादित होती है। elif सिंटैक्टिक शुगर है: यह उस नेस्टिंग से बचाता है जो खाली if स्टेटमेंट्स की एक श्रृंखला बनाएगी। प्रत्येक शर्त का मूल्यांकन आलसी रूप से होता है, केवल तभी जब सभी पूर्ववर्ती शर्तें falsy हों।

python
score = 87

if score >= 90:
    print("A grade")
elif score >= 80:
    print("B grade")
elif score >= 70:
    print("C grade")
else:
    print("Below C")

नियम:

  • if आवश्यक है और हमेशा पहले आता है
  • elif ("else if" का संक्षिप्त रूप) वैकल्पिक है और आप जितने चाहें उतने रख सकते हैं
  • else वैकल्पिक है, उन सभी को संभालता है जो मेल नहीं खाते, और अंत में आता है
  • Python प्रत्येक ब्लॉक के अंदर क्या है यह चिह्नित करने के लिए इंडेंटेशन (4 स्पेस) का उपयोग करता है; कोई ब्रेसेस नहीं हैं

इंडेंटेशन वैकल्पिक या सजावटी नहीं है। Python इसका उपयोग संरचना परिभाषित करने के लिए करता है। असंगत इंडेंटेशन एक सिंटैक्स त्रुटि है।

एक-लाइन शर्तें

सरल हाँ/नहीं असाइनमेंट के लिए, Python का एक संक्षिप्त एक-लाइन रूप है जिसे टर्नरी एक्सप्रेशन कहा जाता है: value_if_true if condition else value_if_false। इसका उपयोग केवल तब करें जब तर्क वास्तव में सरल हो और एक वाक्य की तरह पढ़ा जाए।

सशर्त अभिव्यक्ति (टर्नरी ऑपरेटर) एक शर्त के आधार पर दो मानों में से एक का मूल्यांकन करती है। यह एक अभिव्यक्ति है, स्टेटमेंट नहीं, इसलिए यह कहीं भी दिखाई दे सकती है जहाँ एक मान अपेक्षित है: f-string के अंदर, फ़ंक्शन तर्क के रूप में, असाइनमेंट में। सरल हाँ/नहीं मामलों के लिए इसका उपयोग करें; elif से जुड़ी किसी भी चीज़ के लिए, पूर्ण संस्करण लिखें।

सशर्त अभिव्यक्ति x if condition else y एक एकल अभिव्यक्ति है जो शर्त का मूल्यांकन करती है और दूसरी शाखा को निष्पादित किए बिना x या y लौटाती है। यह POP_JUMP_IF_FALSE बाइटकोड के संयोजन में मैप होती है। if/else ब्लॉक के विपरीत, यह कई स्टेटमेंट्स में नहीं फैल सकती और elif शामिल नहीं कर सकती; जटिल शाखाओं के लिए, पूर्ण if/elif/else ब्लॉक अधिक स्पष्ट हैं।

python
label = "pass" if score >= 50 else "fail"

यह एक टर्नरी एक्सप्रेशन है; यह एक वाक्य की तरह पढ़ा जाता है। इसका उपयोग तब करें जब तर्क वास्तव में सरल हो। elif से जुड़ी किसी भी चीज़ के लिए, पूर्ण संस्करण लिखें।

while लूप

एक while लूप अपने ब्लॉक को तब तक दोहराता है जब तक उसकी शर्त True हो। इसका उपयोग तब करें जब आप पहले से नहीं जानते कि लूप कितनी बार चलना चाहिए, उदाहरण के लिए मान्य इनपुट की प्रतीक्षा करना या किसी कार्य के सफल होने तक पुनः प्रयास करना।

while प्रत्येक पुनरावृत्ति से पहले अपनी शर्त का मूल्यांकन करता है और केवल तब ब्लॉक चलाता है जब शर्त truthy हो। उन लूप के लिए इसका उपयोग करें जहाँ बाहर निकलने की शर्त लूप के अंदर बदलने वाली किसी चीज़ पर निर्भर करती है। जब पुनरावृत्तियों की संख्या ज्ञात हो या आप एक संग्रह पर पुनरावृत्ति कर रहे हों, तो for आमतौर पर साफ़ होता है।

while प्रत्येक पुनरावृत्ति से पहले शर्त अभिव्यक्ति पर __bool__ (या __len__) कॉल करता है। बॉडी शर्त को संशोधित कर सकती है। आंतरिक break के साथ while True मुहावरेदार "लूप-अंत-तक" पैटर्न है जब बाहर निकलने की शर्त का मूल्यांकन बॉडी के बीच या अंत में होना चाहिए। break गायब होने वाले अनंत लूप हैंग का एक सामान्य स्रोत हैं।

python
lives = 3

while lives > 0:
    print(f"Lives remaining: {lives}")
    lives -= 1

print("Game over")

while तब सबसे अच्छा होता है जब आप पहले से नहीं जानते कि लूप कितनी बार चलेगा। जब आप जानते हैं, या जब आप एक संग्रह पर पुनरावृत्ति कर रहे हैं, तो for साफ़ होता है।

break और continue

break लूप को तुरंत बाहर निकाल देता है, चाहे कितनी भी पुनरावृत्तियाँ शेष हों। continue वर्तमान पुनरावृत्ति के शेष भाग को छोड़ देता है और शर्त जाँच पर वापस कूदता है। दोनों केवल उस सबसे आंतरिक लूप को प्रभावित करते हैं जिसके अंदर वे हैं।

break निकटतम संलग्न लूप को समाप्त करता है, नियंत्रण को इसके बाद के पहले स्टेटमेंट में स्थानांतरित करता है। continue वर्तमान लूप बॉडी के शेष भाग को छोड़ देता है और शर्त जाँच से पुनः शुरू होता है (या for लूप में अगली पुनरावृत्ति)। दोनों केवल सबसे आंतरिक संलग्न लूप को प्रभावित करते हैं।

break एक BREAK_LOOP बाइटकोड उत्सर्जित करता है जो लूप के कोड ब्लॉक से बाहर निकलता है और किसी भी संबंधित else क्लॉज को छोड़ देता है। continue CONTINUE_LOOP (या संदर्भ के आधार पर JUMP_ABSOLUTE) उत्सर्जित करता है, जो लूप हेडर से फिर से शुरू होता है। दोनों निकटतम संलग्न लूप तक सीमित हैं; Python में कोई लेबल किया गया break नहीं है। नेस्टेड लूप से बाहर निकलने के लिए, एक बूलियन फ़्लैग का उपयोग करें या return के साथ एक फ़ंक्शन में पुनर्संरचित करें।

break लूप को तुरंत बाहर निकालता है:

python
target = 5
num    = 0

while True:
    num += 1
    if num == target:
        print(f"Found {target}")
        break   # लूप रोकें

break के साथ while True: एक मान्य और सामान्य पैटर्न है जब बाहर निकलने की शर्त जटिल हो या लूप बॉडी के अंत में होनी चाहिए।

continue वर्तमान पुनरावृत्ति के शेष भाग को छोड़ देता है और शर्त जाँच पर वापस जाता है:

python
num = 0

while num < 10:
    num += 1
    if num % 2 == 0:
        continue    # सम संख्याएँ छोड़ें
    print(num)      # केवल विषम संख्याएँ प्रिंट होती हैं: 1, 3, 5, 7, 9

for लूप

एक for लूप एक अनुक्रम के माध्यम से एक समय में एक आइटम जाता है: एक सूची, एक स्ट्रिंग, संख्याओं की एक श्रेणी। for के बाद जो वेरिएबल आप नाम देते हैं, वह क्रम में प्रत्येक आइटम प्राप्त करता है। आप स्वयं एक काउंटर का प्रबंधन नहीं करते या लंबाई की जाँच नहीं करते।

for iterable पर iter() का आह्वान करके एक इटरेटर प्राप्त करता है, फिर उस पर next() कॉल करता है जब तक StopIteration न हो। इसका मतलब है कि for किसी भी ऐसी चीज़ पर काम करता है जो इटरेटर प्रोटोकॉल लागू करती है: सूचियाँ, स्ट्रिंग्स, dicts, फ़ाइलें, ranges, और कस्टम ऑब्जेक्ट। यह इंडेक्स अनुक्रमों तक सीमित नहीं है।

for target in iterable एक इटरेटर ऑब्जेक्ट प्राप्त करने के लिए iter(iterable) कॉल करता है, फिर बार-बार next(iterator) कॉल करता है और परिणाम को target से बांधता है जब तक StopIteration raise न हो। for लूप StopIteration को आंतरिक रूप से पकड़ता है। __iter__ (या __iter__ और __next__ दोनों) लागू करने वाला कोई भी ऑब्जेक्ट iterable है। इसमें जनरेटर और फ़ाइल ऑब्जेक्ट जैसे आलसी ऑब्जेक्ट शामिल हैं।

python
players = ["आरव", "प्रिया", "रोहन"]

for player in players:
    print(f"Hello, {player}!")

for लूप स्ट्रिंग्स पर भी काम करते हैं (वर्ण दर वर्ण पुनरावृत्ति) और किसी भी अन्य अनुक्रम प्रकार पर।

range()

range() आपके लूप पर जाने के लिए संख्याओं का एक अनुक्रम उत्पन्न करता है। range(5) आपको 0, 1, 2, 3, 4 देता है। आप शुरुआत, अंत, और स्टेप आकार को नियंत्रित कर सकते हैं। जब आपको एक विशिष्ट संख्या में लूप चलाने की आवश्यकता हो तो इसका उपयोग करें।

range(start, stop, step) start से stop तक (लेकिन इसमें शामिल नहीं) पूर्णांक उत्पन्न करता है, step के साथ कदम बढ़ाता है। यह एक आलसी अनुक्रम है: यह एक सूची नहीं बनाता, यह माँग पर संख्याएँ उत्पन्न करता है। यह range(10_000_000) को मेमोरी-कुशल बनाता है। तीनों रूप उल्टी गिनती के लिए नकारात्मक तर्क स्वीकार करते हैं।

range एक प्रकार है, फ़ंक्शन नहीं। range(n) एक range ऑब्जेक्ट बनाता है जो O(1) में सदस्यता और इंडेक्सिंग की गणना करता है बिना अनुक्रम को साकार किए। यह len(), in, स्लाइसिंग, और रिवर्स पुनरावृत्ति का समर्थन करता है। आंतरिक रूप से यह केवल start, stop, और step संग्रहीत करता है। जब आपको केवल पुनरावृत्ति की आवश्यकता हो तो list(range(n)) के बजाय इसे प्राथमिकता दें।

python
for i in range(5):
    print(i)    # 0, 1, 2, 3, 4

range() के तीन रूप हैं:

कॉलयह क्या उत्पन्न करता है
range(5)0, 1, 2, 3, 4
range(2, 6)2, 3, 4, 5
range(0, 10, 2)0, 2, 4, 6, 8 (2 का स्टेप)
range(5, 0, -1)5, 4, 3, 2, 1 (उल्टी गिनती)

range() एक सूची नहीं बनाता। यह एक समय में एक संख्या उत्पन्न करता है, जो बहुत बड़ी श्रेणियों के लिए भी कुशल है।

enumerate()

enumerate() लूप के दौरान आपको इंडेक्स और मान दोनों देता है, इसलिए आपको अलग से एक काउंटर ट्रैक करने की आवश्यकता नहीं है। i, player भाग प्रत्येक पुनरावृत्ति पर स्वचालित रूप से मानों की एक जोड़ी प्राप्त करता है।

enumerate(iterable, start=0) किसी भी इटरेटर को रैप करता है और (index, value) टपल्स yield करता है। start पैरामीटर काउंटर को ऑफसेट करता है लेकिन अंतर्निहित इंडेक्स नहीं बदलता। एक काउंटर वेरिएबल प्रबंधित करने के बजाय enumerate() को प्राथमिकता दें; यह साफ़ है और कम त्रुटि-प्रवण है।

enumerate किसी भी इटरेटर को enumerate ऑब्जेक्ट में रैप करता है जो (count, value) जोड़े yield करता है। start तर्क प्रारंभिक काउंटर मान सेट करता है। for हेडर में अनपैकिंग (for i, v in enumerate(...)) काम करती है क्योंकि प्रत्येक yielded आइटम एक टपल है। enumerate प्रति स्टेप O(1) है, काउंटर के अलावा कोई अतिरिक्त मेमोरी आवंटन नहीं।

python
players = ["आरव", "प्रिया", "रोहन"]

for i, player in enumerate(players):
    print(f"{i + 1}. {player}")
# 1. आरव
# 2. प्रिया
# 3. रोहन

i, player सिंटैक्स को अनपैकिंग कहा जाता है। Python स्वचालित रूप से (index, value) जोड़ी को दो नामों में विभाजित करता है।

डिफ़ॉल्ट रूप से enumerate() 0 से शुरू होता है। इसे बदलने के लिए एक शुरुआती मान पास करें:

python
for i, player in enumerate(players, start=1):
    print(f"{i}. {player}")    # 1 से शुरू होता है

नेस्टेड लूप

आप एक लूप को दूसरे लूप के अंदर रख सकते हैं। आंतरिक लूप बाहरी लूप की प्रत्येक एक पुनरावृत्ति के लिए पूरी तरह से चलता है। इस तरह आप ग्रिड, संयोजन, या किसी भी डेटा को दो स्तरों की संरचना के साथ संसाधित करते हैं।

नेस्टेड लूप में बाहरी लंबाई m और आंतरिक लंबाई n के लिए O(m × n) पुनरावृत्ति गणना होती है। नेस्टेड लूप के अंदर break और continue केवल सबसे आंतरिक लूप को प्रभावित करते हैं। कई स्तरों से बाहर निकलने के लिए, एक फ़्लैग वेरिएबल का उपयोग करें या एक फ़ंक्शन में पुनर्संरचित करें।

प्रत्येक for लूप कॉल एक नया इटरेटर ऑब्जेक्ट बनाता है। नेस्टेड लूप अपने इटरेटर को स्वतंत्र रूप से बनाते हैं। break केवल सबसे आंतरिक लूप से बाहर निकलता है; Python में कोई लेबल किया गया break नहीं है। सामान्य वर्कअराउंड एक फ़्लैग वेरिएबल है या एक फ़ंक्शन में आंतरिक लूप को एन्कैप्सुलेट करना और return का उपयोग करना है। कार्टेशियन उत्पादों के लिए, itertools.product नेस्टेड for लूप से अधिक पठनीय है।

python
rows = [1, 2, 3]
cols = ["A", "B"]

for row in rows:
    for col in cols:
        print(f"{col}{row}", end=" ")
    print()   # प्रत्येक पंक्ति के बाद नई पंक्ति
# A1 B1
# A2 B2
# A3 B3

नेस्टेड लूप के अंदर break और continue केवल सबसे आंतरिक लूप को प्रभावित करते हैं।

Loop-else

Python लूप में एक else क्लॉज हो सकता है जो केवल तभी चलता है जब लूप break से टकराए बिना समाप्त हो। इसका आमतौर पर उपयोग नहीं किया जाता है, लेकिन यह "एक सूची खोजें, और यदि कुछ नहीं मिला, तो यह करें" लिखने का सबसे साफ़ तरीका है।

for या while लूप पर else तब निष्पादित होता है जब लूप सामान्य रूप से पूर्ण होता है (iterable समाप्त हो जाता है या शर्त false हो जाती है) break से टकराए बिना। यह एक अलग found-flag वेरिएबल की आवश्यकता के बिना "खोजें और यदि नहीं मिला तो रिपोर्ट करें" के लिए मुहावरेदार पैटर्न है।

लूप else BREAK_LOOP बाइटकोड द्वारा नियंत्रित होता है: यदि break फायर होता है, तो else ब्लॉक का सेटअप कोड दर्ज नहीं किया जाता। यदि लूप समाप्त हो जाता है, तो else ब्लॉक चलता है। यह if पर एक सादे else से सिमेंटिक रूप से अलग है। मुख्य व्यावहारिक उपयोग search-with-break पैटर्न है; इसके बाहर, यह शायद ही देखा जाता है और इससे अपरिचित पाठकों को भ्रमित कर सकता है।

python
target = "विकास"
names  = ["आरव", "प्रिया", "रोहन"]

for name in names:
    if name == target:
        print(f"Found {target}")
        break
else:
    print(f"{target} not in list")   # चलता है क्योंकि break कभी नहीं फायर हुआ

यदि break चलता है, तो else को छोड़ दिया जाता है। यदि लूप अनुक्रम को समाप्त कर देता है, तो else चलता है। यह एक विशिष्ट पैटर्न है लेकिन एक फ़्लैग वेरिएबल से साफ़ है।

छँटाई

sorted() एक नई छँटी हुई सूची लौटाता है और मूल को अपरिवर्तित छोड़ देता है। .sort() सूची को इन-प्लेस छाँटता है और None लौटाता है। key= तर्क आपको कच्चे मान के अलावा किसी अन्य चीज़ से छाँटने देता है। उदाहरण के लिए, केस-असंवेदनशील रूप से नाम छाँटना या उनके स्कोर द्वारा खिलाड़ी टपल्स छाँटना।

sorted() सुरक्षित डिफ़ॉल्ट है: यह कभी भी मूल को संशोधित नहीं करता। .sort() इन-प्लेस संशोधित करता है और None लौटाता है। दोनों अवरोही क्रम के लिए reverse=True स्वीकार करते हैं। key= तर्क एक फ़ंक्शन लेता है जो तुलना से पहले प्रत्येक तत्व पर लागू होता है। यह छँटाई मानदंड को डेटा से अलग करता है।

दोनों Timsort का उपयोग करते हैं: O(n log n) सबसे खराब स्थिति, लगभग छँटे हुए डेटा पर O(n), स्थिर। .sort() जानबूझकर None लौटाता है (command-query separation)। key= फ़ंक्शन प्रति तत्व एक बार कॉल किया जाता है, प्रति तुलना नहीं, इसलिए महंगी कुंजी गणना दोहराई नहीं जाती। key=str.lower एक unbound मेथड संदर्भ है; key=lambda p: p[1] एक विशिष्ट फ़ील्ड तक पहुँचने के लिए एक इनलाइन फ़ंक्शन है।

python
scores = [87, 42, 96, 55, 71]

ranked = sorted(scores)           # [42, 55, 71, 87, 96] (नई सूची)
scores.sort()                     # मूल सूची को छाँटता है, None लौटाता है
scores.sort(reverse=True)         # [96, 87, 71, 55, 42]

दोनों एक key= तर्क स्वीकार करते हैं: तुलना से पहले प्रत्येक आइटम पर लागू एक फ़ंक्शन:

python
names = ["रोहन", "आरव", "प्रिया"]
sorted(names, key=str.lower)       # केस-असंवेदनशील छँटाई

players = [("आरव", 87), ("प्रिया", 96), ("रोहन", 55)]
sorted(players, key=lambda p: p[1])   # स्कोर के अनुसार छँटाई

lambda क्या है?

lambda p: p[1] एक एक-लाइन फ़ंक्शन है। यह एक प्लेयर टपल लेता है और स्कोर लौटाता है। लैम्ब्डा फ़ंक्शन Lambda, comprehensions, and zip अध्याय में कवर किए गए हैं।

सरल मामलों के लिए, sorted() का उपयोग करें। उन सूचियों के लिए जिन्हें आप इन-प्लेस संशोधित करना चाहते हैं, .sort() का उपयोग करें।

व्यवहार में

स्कोर्स के माध्यम से लूप करें, कुल जमा करें, पास होने वाले ग्रेड गिनें, और एक सारांश प्रिंट करें:

python
raw_scores = [87, 42, 96, 55, 71, 63]

total   = 0
passing = 0

for score in raw_scores:
    total += score
    if score >= 60:
        passing += 1

average = total / len(raw_scores)
print(f"Average: {average:.1f}")
print(f"Passing: {passing}/{len(raw_scores)}")
print(f"Top score: {sorted(raw_scores, reverse=True)[0]}")

फ़ाइलों की एक सूची को छँटे हुए क्रम में संसाधित करें, बहुत बड़ी फ़ाइलों को छोड़ें, और रिपोर्ट करें कि कितनी को छोड़ा गया था:

python
files = [
    {"name": "report_jan.csv", "size_mb": 12},
    {"name": "report_feb.csv", "size_mb": 850},
    {"name": "report_mar.csv", "size_mb": 7},
]

MAX_SIZE = 100
skipped  = 0

for f in sorted(files, key=lambda x: x["name"]):
    if f["size_mb"] > MAX_SIZE:
        print(f"Skipping {f['name']} ({f['size_mb']} MB, too large)")
        skipped += 1
    else:
        print(f"Processing {f['name']}...")

print(f"\nDone. {skipped} file(s) skipped.")

त्रुटियों के लिए एक request log स्कैन करें, फिर एक retry लूप का उपयोग करें जो सफलता पर या जब प्रयास सीमा से टकराए तब बाहर निकलता है:

python
requests = [
    {"method": "GET",  "path": "/users",  "status": 200},
    {"method": "POST", "path": "/users",  "status": 201},
    {"method": "GET",  "path": "/broken", "status": 500},
]

errors = []

for req in requests:
    if req["status"] >= 400:
        errors.append(req)

if errors:
    print(f"{len(errors)} error(s) in request log:")
    for err in errors:
        print(f"  {err['method']} {err['path']} -> {err['status']}")
else:
    print("All requests succeeded")

attempts    = 0
max_retries = 3
success     = False

while attempts < max_retries and not success:
    attempts += 1
    print(f"Attempt {attempts}...")
    success = attempts >= 2   # दूसरी कोशिश पर सफलता का अनुकरण करें

print("Connected" if success else "Failed after all retries")