अध्याय 11

for लूप और range — निश्चित संख्या में काम दोहराना

जब पता हो कि कितनी बार दोहराना है, तो for लूप ही सही चुनाव है। range के तीन रूप, अंतिम मान क्यों छूटता है, और for तथा while के बीच सही चुनाव।

35 मिनटPython 3.12
  1. 1समस्या
  2. 2समझें
  3. 3उदाहरण
  4. 4अनुमान
  5. 5स्वयं करें
  6. 6चुनौती

वह समस्या जिसे हम हल कर रहे हैं

पिछले पाठ में, 1 से 5 तक जोड़ने में चार पंक्तियाँ लगी थीं, जिनमें से दो केवल गिनती रखने के लिए थीं — एक प्रारंभिक मान और एक वृद्धि। यदि आप वृद्धि भूल जाते हैं, तो अनंत लूप (infinite loop) बन जाता है।

लेकिन उस तरह के काम में एक बात ध्यान देने योग्य है: हमें पहले से पता था कि लूप कितनी बार चलेगा। पाँच बार। जब ऐसा हो, तो गिनती का हिसाब खुद रखने की कोई आवश्यकता नहीं है — आप यह काम पायथन को सौंप सकते हैं।

यही काम for लूप करता है। और चूँकि गिनती आपके हाथ में नहीं होती, एक for लूप कभी अनंत नहीं हो सकता — जो कि इसका सबसे बड़ा लाभ है।

इस मिशन के अंत तक आप सीखेंगे

  • for लूप के साथ कोड को एक निश्चित संख्या में चलाना
  • range() के तीनों रूपों का उपयोग करना
  • यह समझना कि range(1, 5) पाँच नहीं बल्कि चार संख्याएँ क्यों देता है
  • किसी टेक्स्ट (स्ट्रिंग) के प्रत्येक अक्षर पर लूप चलाना
  • यह तय करना कि किसी कार्य के लिए for और while में से कौन बेहतर है

पूर्वापेक्षाएँ: while लूप — शर्त सत्य रहने तक चलना.


सबसे सरल रूप

python
for number in range(5):
    print(number)
text
0
1
2
3
4

एक ही पंक्ति में तीन पंक्तियों का काम हो गया, और किसी काउंटर को प्रबंधित करने की ज़रूरत नहीं पड़ी। इसे ऐसे पढ़ें: "संख्याओं के लिए जो `range(5)` उत्पन्न करता है, ब्लॉक को एक बार चलाएं — और हर बार, उस संख्या को `number` में रखें।"

दो बातें तुरंत स्पष्ट होती हैं:

यह शून्य (0) से शुरू होता है, और 5 कभी नहीं आता — कुल पाँच संख्याएँ हैं, लेकिन 0 से 4 तक। यह वही नियम है जो पायथन हर जगह लागू करता है: जैसे स्लाइस में अंतिम इंडेक्स शामिल नहीं होता, वैसे ही range में भी होता है।

number चर का नाम आपकी पसंद है। for i in range(5) भी उतना ही सही है, और i काउंटर के लिए पारंपरिक नाम है। लेकिन जब संख्या का कोई अर्थ हो, तो अर्थ के अनुसार नाम दें — for student_number in range(30) अपने आप समझ में आता है।

range() के तीन रूप

python
print("--- range(5) ---")
for i in range(5):
    print(i, end=" ")

print()
print("--- range(2, 6) ---")
for i in range(2, 6):
    print(i, end=" ")

print()
print("--- range(0, 10, 3) ---")
for i in range(0, 10, 3):
    print(i, end=" ")

print()
print("--- range(5, 0, -1) ---")
for i in range(5, 0, -1):
    print(i, end=" ")
print()
text
--- range(5) ---
0 1 2 3 4 
--- range(2, 6) ---
2 3 4 5 
--- range(0, 10, 3) ---
0 3 6 9 
--- range(5, 0, -1) ---
5 4 3 2 1

नियम:

  • range(stop) — 0 से शुरू होता है, stop से ठीक पहले समाप्त होता है
  • range(start, stop) — start से शुरू होता है, stop से ठीक पहले समाप्त होता है
  • range(start, stop, step) — हर बार step के मान से आगे बढ़ता है; ऋणात्मक step उल्टी गिनती करता है

अंतिम दो को देखें: range(0, 10, 3) देता है 0 3 6 9 — अगला 12 होगा, जो 10 से अधिक है, इसलिए यह रुक जाता है। और range(5, 0, -1) देता है 5 4 3 2 1 — 0 कभी नहीं आता, क्योंकि अंतिम मान यहाँ भी बाहर रहता है।

अंतिम मान को बाहर क्यों रखा जाता है? क्योंकि इससे अंकगणित आसान हो जाता है। range(0, 5) में कितनी संख्याएँ हैं? 5 - 0, यानी पाँच। range(3, 8) में? 8 - 3, यानी पाँच। घटाएं और आपको गिनती मिल जाएगी, एक जोड़ने या घटाने की चिंता किए बिना। और दो रेंज पास-पास रखने पर — range(0, 5) और range(5, 10) — कुछ भी नहीं छूटता और कुछ भी दोहराया नहीं जाता।

जब आपको एक से दस तक चाहिए

यह गलती इतनी बार होती है कि इसके लिए एक अलग खंड होना चाहिए:

python
print("गलत — 9 पर रुक जाता है:")
for i in range(1, 10):
    print(i, end=" ")

print()
print("सही — 10 को शामिल करता है:")
for i in range(1, 11):
    print(i, end=" ")
print()
text
गलत — 9 पर रुक जाता है:
1 2 3 4 5 6 7 8 9 
सही — 10 को शामिल करता है:
1 2 3 4 5 6 7 8 9 10

एक पंक्ति में नियम: stop के रूप में वह संख्या लिखें जो आपके अंतिम वांछित मान से एक अधिक हो।

संचय करना — अब आसान तरीके से

python
total = 0

for number in range(1, 6):
    total = total + number

print("Sum of 1 to 5:", total)
text
Sum of 1 to 5: 15

इसी काम के while संस्करण से इसकी तुलना करें: कोई काउंटर बनाने की ज़रूरत नहीं, कोई वृद्धि करने की ज़रूरत नहीं, अनंत लूप का कोई जोखिम नहीं। केवल एक्यूमुलेटर को अभी भी लूप के बाहर शुरू करना पड़ता है, बिल्कुल पहले की तरह।

टेक्स्ट पर लूप चलाना

for केवल संख्याओं पर ही नहीं चलता — यह टेक्स्ट पर भी एक-एक अक्षर करके चलता है:

python
word = "Python"

for letter in word:
    print(letter, end="-")
print()

vowel_count = 0
for letter in "programming":
    if letter in "aeiou":
        vowel_count = vowel_count + 1

print("Vowels:", vowel_count)
text
P-y-t-h-o-n-
Vowels: 3

यहाँ किसी range की आवश्यकता नहीं है — for letter in word सीधे अक्षरों पर चलता है। यह इंडेक्स गणित करने से बहुत सरल है, और IndexError का कोई जोखिम नहीं रहता।

break और continue यहाँ भी काम करते हैं

बिल्कुल वैसे ही जैसे वे while में करते थे:

python
for number in range(1, 20):
    if number % 7 == 0:
        print("First multiple of 7:", number)
        break
text
First multiple of 7: 7

for और while के बीच चुनाव

बस एक प्रश्न पूछें: क्या लूप शुरू होने से पहले दोहराव की संख्या ज्ञात है?

यदि हाँ, तो for:

  • पाँच बार चलाना
  • 1 से 100 तक जाना
  • किसी शब्द के प्रत्येक अक्षर को देखना
  • किसी सूची (list) की प्रत्येक वस्तु के साथ कुछ करना

यदि नहीं, तो while:

  • जब तक इनपुट मान्य न हो तब तक पूछते रहना
  • जब तक कोई quit टाइप न करे तब तक चलाना
  • जब तक फ़ाइल में पंक्तियाँ बची हैं तब तक पढ़ना

संदेह होने पर, for चुनें। कारण सरल है: for लूप का समाप्त होना सुनिश्चित होता है, जबकि while का नहीं। जहाँ दोनों काम कर सकते हैं, वहाँ वह विकल्प बेहतर है जिसमें गलतियों की संभावना कम हो।


एक संपूर्ण उदाहरण

multiplication.py:

python
# एक पहाड़ा (multiplication table) और फिर एक संक्षिप्त सारांश प्रिंट करें
number = int(input("Which table? "))
upto = int(input("Up to?       "))

print()
print(f"--- Table of {number} ---")

total = 0
for i in range(1, upto + 1):
    result = number * i
    total = total + result
    print(f"{number} x {i:2} = {result:4}")

print()
print(f"Rows    : {upto}")
print(f"Sum     : {total}")
print(f"Average : {total / upto:.2f}")
text
Which table? 7
Up to?       5

--- Table of 7 ---
7 x  1 =    7
7 x  2 =   14
7 x  3 =   21
7 x  4 =   28
7 x  5 =   35

Rows    : 5
Sum     : 105
Average : 21.00

तीन बातों पर ध्यान दें। पहला, range(1, upto + 1) — upto तक पहुँचने के लिए एक अधिक लिखना पड़ा। दूसरा, {i:2} और {result:4} — f-string के अंदर आप बता सकते हैं कि किसी संख्या को कितनी चौड़ाई लेनी चाहिए, जिससे कॉलम संरेखित रहते हैं। तीसरा, total लूप के बाहर शुरू होता है और अंदर बढ़ता है।


जब यह टूटता है

अंतिम संख्या गायब है range(1, 10) वास्तव में 9 पर समाप्त होता है। stop में एक जोड़ें: range(1, 11).

TypeError: 'float' object cannot be interpreted as an integer range() केवल पूर्ण संख्याएँ स्वीकार करता है। range(2.5) या range(1, n / 2) नहीं चलेगा — int() से बदलें, या // से भाग दें।

SyntaxError: expected ':' for वाली पंक्ति के अंत में कोलन (:) छूट गया है।

IndentationError: expected an indented block after 'for' statement लूप के अंदर की पंक्ति इंडेंट नहीं की गई थी।

लूप कभी चला ही नहीं range खाली है। range(5, 0) कुछ भी नहीं देता — उल्टी गिनती करने के लिए आपको तीसरे तर्क की आवश्यकता होती है: range(5, 0, -1).

लूप के बाद कुल योग 0 रह जाता है total = 0 पंक्ति लूप के अंदर चली गई है, इसलिए यह हर बार रीसेट हो जाती है। इसे बाहर होना चाहिए।