1.3.10 · Coding › Python Intermediate
Intuition 30-second picture
Ek iterator ek tape player jaisa hai jisme sirf ek button hota hai: next . Dabaao, agla item milta hai; tape khatam hone ke baad dabaao, toh ==StopIteration raise hota hai==. for loop bas woh code hai jo us button ko tab tak dabata rehta hai jab tak use "tape khatam" ka signal nahi milta — aur phir quietly ruk jaata hai.
Gehri baat yeh hai: iteration ek protocol hai, koi magic nahi . Jo bhi object is protocol ko follow karta hai, woh loopable ban jaata hai — chahe aapki apni classes hi kyun na hon.
Intuition List use kyun nahi karte?
Ek list saare elements ek saath memory mein store karti hai. Agar aapko infinitely many primes mein se pehle 10 prime numbers chahiye, toh aap "saare primes" list mein store nahi kar sakte. Ek iterator ek waqt mein ek element compute karta hai, demand pe (lazy evaluation). Yeh memory bachata hai aur aapko infinite ya streaming sequences represent karne deta hai.
YEH problem kya solve karta hai: for x in something: lists, files, dictionaries, ranges, aur aapke apne objects pe uniformly kaise kaam kar sakta hai — bina for ke unke internals jaane? Jawab: yeh sab ek hi chhote se iterator protocol ko speak karne pe raazi hote hain.
Definition Iterable vs Iterator
Ek iterable koi bhi object hai jisme ek ==__iter__()== method hoti hai jo ek iterator return karti hai.
Ek iterator koi bhi object hai jisme ek ==__next__() method hoti hai jo agla item return karti hai, aur exhaust hone par StopIteration raise karta hai==. Iterator ka __iter__() khud usse return karta hai.
Toh: iterable = "Main tumhe ek naaya tape player de sakta hoon." Iterator = "Main hi tape player hoon; mera button dabaao."
Countdown iterator (derivation)
Goal: Countdown(3) ko 3, 2, 1 yield karna chahiye phir ruk jaana chahiye.
class Countdown :
def __init__ (self, start):
self .current = start # state lives on the object
def __iter__ (self):
return self # I am my own iterator
def __next__ (self):
if self .current <= 0 : # exhaustion check FIRST
raise StopIteration # signal: tape ended
value = self .current # remember what to return
self .current -= 1 # advance the state
return value # hand back this item
Har step kyun?
__iter__ self return karta hai → yeh "ek iterator ka __iter__ khud usse return karta hai" satisfy karta hai, toh Countdown dono iterable aur iterator hai.
Exhaustion check computing/returning se pehle aata hai → warna hum 0 ya negatives return kar dete.
Hum value decrementing se pehle save karte hain → humein current count return karna hai, phir agli baar ke liye prepare karna hai.
Run karein:
for n in Countdown( 3 ):
print (n) # 3, 2, 1
infinite iterator: even numbers
class Evens :
def __init__ (self):
self .n = - 2
def __iter__ (self):
return self
def __next__ (self):
self .n += 2 # never raises StopIteration → infinite!
return self .n
Yeh kyun matter karta hai: Saare even numbers ki list impossible hai; unka iterator trivial hai. Savdhani se use karein — kabhi bhi list(Evens()) mat karein (yeh hamesha ke liye hang ho jaata hai). next() manually ya itertools.islice use karein.
next() aur default ke saath manual driving
it = iter ([ 10 , 20 ])
print ( next (it)) # 10 — Kyun? pehla button press
print ( next (it)) # 20
print ( next (it, 'done' )) # 'done' — Kyun? default StopIteration ko suppress karta hai
next(it, default) raise karne ki jagah default return karta hai — tab kaam aata hai jab aapko try/except ke bina ek item chahiye.
Intuition Inhe alag kyun rakhte hain?
Ek list iterable hai lekin khud apna iterator NAHI hai. Har iter(my_list) apni position ke saath ek brand-new iterator deta hai. Isliye aap ek hi list pe do nested for loops independently chala sakte ho:
nums = [ 1 , 2 ]
for a in nums: # iterator A
for b in nums: # iterator B — independent position
print (a, b) # (1,1)(1,2)(2,1)(2,2)
Agar list khud apna iterator hoti (single shared position), toh inner loop usse exhaust kar deta aur outer loop kabhi aage nahi badhta. Yahi iterable/iterator distinction ka poora reason hai.
Common mistake "Meri class par mera
for loop sirf ek baar chalta hai, phir hamesha ke liye empty ho jaata hai."
Galat idea sahi kyun lagta hai: Aapne __iter__ ko self return karne diya, jo kaam karta hai — ek baar. Lekin kyunki object hi iterator hai, uski state (self.current) consume ho jaati hai aur kabhi reset nahi hoti. Dobara loop karne par exhausted state se shuru hota hai.
Fix: Reusable iterables ke liye, __iter__ se ek fresh iterator object return karein:
class CountdownReusable :
def __init__ (self, start): self .start = start
def __iter__ (self):
return Countdown( self .start) # new tape player each loop
Common mistake "Main rukne ke liye
raise StopIteration ki jagah return karta hoon."
Sahi kyun lagta hai: Ek generator mein return iteration khatam karta hai. Lekin haath se likhe __next__ mein, return sirf ek value return karta hai (aksar None) — loop hamesha ke liye chalta rehta hai ya Nones yield karta hai.
Fix: __next__ mein explicitly raise StopIteration karein.
__iter__ bhool gaya aur sirf __next__ likha."
Sahi kyun lagta hai: __next__ core lagta hai. Lekin for/iter() pehle __iter__ call karta hai; uske bina aapko milega TypeError: object is not iterable.
Fix: hamesha dono provide karein; iterator ka __iter__ self return karta hai.
Common mistake Generator ke andar purpose se
StopIteration raise karna.
PEP 479 ke baad se, ek StopIteration jo generator ke bahar bubble out hoti hai woh RuntimeError ban jaati hai. Generators mein return use karein; sirf haath se likhi iterator classes raise StopIteration karein.
Recall Woh 20% jo 80% deta hai
iter(obj) → obj.__iter__() call karta hai → ek iterator return karta hai.
next(it) → it.__next__() call karta hai → agla item, ya StopIteration raise karta hai.
for = iter + repeated next + StopIteration catch + break.
Iterator ka __iter__ self return karta hai; ek reusable iterable ek naaya iterator return karta hai.
Recall Feynman: 12-saal ke bachchhe ko explain karo
Ek Pez candy dispenser imagine karo. Aap upar dabaate ho (next ) aur ek candy bahar aati hai. Dabaate aur khaate raho. Jab khaali ho jaata hai, dabaane pe ek chhoti si click aati hai jiska matlab hai "sab khatam" (StopIteration ) — isliye tumhara dost (for loop ) jaanta hai ki poochhna band karo. Dispenser khud iterator hai. Candy ki ek thaili list jaisi hai: woh khud dispenser nahi hai, lekin jab bhi share karna ho toh tum us se ek fresh dispenser nikal sakte ho — yahi kaam __iter__ list ke liye karta hai: woh tumhe har baar ek naya dispenser deta hai.
Mnemonic Protocol yaad rakhne ka tarika
"I Need to Stop" →
I ter (__iter__ iterator deta hai),
N ext (__next__ item deta hai),
Stop Iteration (end signal deta hai).
Generators — yield, lazy evaluation — generators tumhare liye yeh protocol automatically implement karte hain.
for loops and comprehensions — hood ke neeche iter/next pe bane hain.
itertools — islice, count, chain — composable iterators, infinite waalon ko safely handle karna.
Lazy evaluation and memory efficiency — iterators ke peeche ka WHY.
Dunder (magic) methods — __iter__/__next__ is family ka hissa hain.
StopIteration and PEP 479 — generators ko kyun return karna chahiye, raise nahi.
Iterator protocol mein kaun se do methods define hote hain? __iter__ (iterator return karta hai) aur __next__ (agla item return karta hai / StopIteration raise karta hai).
Iterator ka __iter__ kya return karta hai? self.
Iterable aur iterator mein kya difference hai? Iterable mein __iter__ hoti hai jo iterator return karti hai; iterator mein __next__ hoti hai aur aage badhne par consume hota hai.
for x in obj internally kaise kaam karta hai?it = iter(obj); try mein next(it) loop karo, StopIteration pakad ke break karo.
Ek iterator kaise signal karta hai ki woh exhaust ho gaya hai? Woh StopIteration raise karta hai.
next(it, default) kya karta hai?Exhaust hone par StopIteration raise karne ki jagah default return karta hai.
Lists apne khud ke iterators kyun nahi hote? Taaki har iter(list) ek independent position de sake, jisse nested/independent loops ho sakein.
Reusable iterable ke __iter__ ko ek NAYA iterator kyun return karna chahiye? Warna shared state exhaust ho jaati hai aur dobara loop karne par kuch nahi milta.
Haath se likhe __next__ mein iteration kaise rokein? raise StopIteration (return nahi).
Generator ke andar kaise rokein — aur StopIteration raise kyun nahi karte? return use karo; PEP 479 ke baad se leaked StopIteration RuntimeError ban jaati hai.
List stores all in memory
Need lazy on-demand values