1.2.34 · D5 · HinglishIntroduction to Programming (Python)

Question bankList comprehensions — `[expr for x in iterable if condition]`

2,707 words12 min read↑ Read in English

1.2.34 · D5 · Coding › Introduction to Programming (Python) › [[1.2.34 List comprehensions — `[expr for x in iterable if condition]`|List comprehensions — `[expr for x in iterable if condition]`]]

Yeh page conceptual trip-wires ka ek set hai [[1.2.34 List comprehensions — [expr for x in iterable if condition] (Hinglish)|list comprehensions]] ke liye. Yahan koi bhaari computation nahi hai — har item ek misconception ya ek boundary case ko target karta hai. Har prompt padho, apna jawab zor se decide karo, phir reveal karo.

Placeholders ka matlab (pehle yeh padho)

Traps se pehle, template [expr for x in iterable if condition] mein use hone wale placeholder names ko samajh lo. Is page ke har formula mein yahi exact stand-ins use hote hain, isliye inhe yahan ek baar define karte hain aur naam kabhi nahi badalte:

Poore page mein, parent note ke do anchors yaad rakho:

  • Execution order hai forifexpr (item pick karo, test karo, phir build karo), chahe hum expr pehle padhte hain.
  • Do alag ifs hote hain: filter if (koi else nahi, for ke baad jaata hai, items drop karta hai) aur conditional if/else (ek ternary, for se pehle jaata hai, ek value choose karta hai). Mnemonic: "Choose-before, Cut-after."

Neeche ki figure un dono anchors ko ek picture mein convert karti hai — traps karte waqt ise dekhte raho:

Figure — List comprehensions — `[expr for x in iterable if condition]`

Figure ko top-to-bottom padho. Top line mein, red arrow ternary slot (a if t else b) ko point karta hai jo for se pehle baitha hai — yeh hai "choose-before", jahan t values a aur b ke beech choose karta hai. Black arrow filter cond ko point karta hai jo for ke baad baitha hai — "cut-after", jahan cond items drop karta hai. Neeche ki chain dikhati hai ki actually kya run hota hai: red for box pehle fire karta hai (x pick karo), phir if (test karo), phir expr (build karo) — reading order ka exactly ulta. Is page ka har trap in dono axes mein se ek ka stress-test hai: kaun sa if aur expr kab run hota hai.

Loop rewrites (teeno shapes)

Har comprehension ka ek jaisa skeleton nahi hota. Yahan teeno common shapes ke loop translations hain, taaki koi case unexplained na rahe. (Yaad karo it = iterable, cond = condition, aur a/b/t ternary ki do values aur uska test hain, sab upar define hain.)


Sahi hai ya galat — justify karo

Har list comprehension ko equivalent plain for loop ke saath append ke roop mein rewrite kiya ja sakta hai.
Sahi — ek comprehension pure syntactic sugar hai; map-only r=[]; for x in it: r.append(expr) ban jaata hai, aur filter aur ternary wala r=[]; for x in it: if cond: r.append(a if t else b) ban jaata hai. Translation hamesha exist karta hai.
if condition filter part mandatory hai.
Galat — yeh optional hai. Iske bina, iterable ka har item rakha jaata hai aur expr tak pass hota hai, toh comprehension ek pure transform hai.
[x**2 for x in range(10) if x % 2 == 0] mein, x**2 das saare numbers ke liye compute hota hai.
Galat — filter expr se pehle run hota hai. Sirf paanch even numbers if se bach ke aate hain, isliye x**2 exactly paanch baar compute hota hai, das baar nahi.
Comprehension hamesha ek list return karta hai, chahe koi bhi brackets use ho.
Galat — sirf square brackets [...] ek list banate hain. {...} ek set ya dict banata hai, aur (...) ek lazy generator banata hai, list nahi.
[n if n > 0 else n for n in nums] aur [n for n in nums if n > 0] same length ki lists produce karte hain.
Galat — pehla ek ternary hai jo har item ko map karta hai (same length as nums, negatives ko yahan unchanged rakhta hai); doosra filter karta hai, isliye woh usually shorter hota hai (negatives bilkul drop kar deta hai).
[cell for row in grid for cell in row] mein, sabse right wala for outermost loop hai.
Galat — sabse left wala for outermost loop hai. Multiple fors top-to-bottom / outer-to-inner padhte hain, exactly nested for loops ki tarah.
Comprehension equivalent loop se hamesha faster aur clearer hota hai, isliye ise har jagah use karna chahiye.
Galat — yeh aksar simple maps aur filters ke liye faster aur cleaner hota hai, lekin nested ifs, side effects, ya 100-char lines readability barbad kar deti hain. Agar aap ise ek sentence ke roop mein zor se nahi padh sakte, toh loop use karo.
[x for x in range(3)] mein variable x comprehension khatam hone ke baad surrounding code mein leak ho jaata hai.
Galat — Python 3 mein loop variable comprehension ke andar scoped hota hai; yeh bahar exist nahi karta (ya kuch overwrite nahi karta), plain for loop ke unlike.
[print(x) for x in range(3)] teen numbers print karne ka ek acha tarika hai.
Galat — yeh kaam karta hai lekin misuse hai. Comprehensions lists banane ke liye hain; yahan aap ek bekar [None, None, None] bhi create karte ho. Printing jaise side effects ke liye plain for loop use karo.
Ek for ke baad do if filters daal sakte ho, aur item ke liye dono pass hone chahiye.
Sahi — [x for x in xs if x > 0 if x < 10] filters ko and ki tarah chain karta hai; ek item sirf tabhi survive karta hai jab har filter True ho.
Multi-for comprehension mein, ek filter sirf outermost loop variable ko test kar sakta hai.
Galat — ek filter apne left mein sabse recent for se bind hota hai, isliye [x for a in A for x in a if x>0] inner x ko filter karta hai, a ko nahi.

Error dhundho

[x for x in nums if x > 0 else 0] — kya galat hai?
Yeh ek SyntaxError hai. Bare filter if (after for) kabhi else nahi le sakta. Agar aap else chahte ho, toh aapko for se pehle ternary chahiye: [x if x > 0 else 0 for x in nums].
[len(w) for w if len(w) > 3] — kya missing hai?
Loop ka in iterable part. Har for x ko ek source chahiye: yeh for w in words padhna chahiye, warna Python ke paas items draw karne ki jagah hi nahi hai.
squares = [x**2 for x in range(5)]; print(x) — Python-2 veteran ko yeh kyun surprise kar sakta hai?
Python 3 mein, x comprehension se bahar leak nahi hota, isliye print(x) NameError raise karta hai (jab tak x pehle se define nahi tha). Purani Python-2 ki aadat thi ki loop variable survive karta hai.
result = [i + j for i in range(2)] for j in range(2)]dono faults batao.
Pehla, ek stray closing bracket hai: [...] range(2) ke baad close ho jaata hai, isliye baaki for j ... )] ek SyntaxError hai. Doosra, agar fix bhi kar do, toh for j brackets ke andar belong karta hai. Sahi form dono loops merge karta hai: [i + j for i in range(2) for j in range(2)].
even_or_zero = [x if x % 2 == 0 for x in nums] — kya toota hua hai?
expr ke roop mein use hone wala ternary complete hona chahiye: ise else chahiye. Ya toh ise add karo (x if x % 2 == 0 else None) ya, agar aap filter karna chahte the, toh ise for ke baad move karo: [x for x in nums if x % 2 == 0].
[row for cell in row for row in grid] — yeh NameError kyun raise karta hai?
fors galat order mein hain. Sabse left/pehla for outer name define karna chahiye; yahan cell in row row exist karne se pehle likha gaya hai. Sahi order hai for row in grid for cell in row.

Why questions

expr written form mein pehle kyun appear karta hai jab actually yeh last run hota hai?
Kyunki hum ise English sentence ki tarah padhte hain "give me expr for each x" — design reading intent (aap kya chahte ho) ko execution mechanics (kaise banta hai) ke upar favour karta hai.
Ternary if/else for se pehle kyun jaata hai lekin filter if baad mein?
Ternary expr ka hissa hai (ise output slot ke liye ek value return karni hai, jo pehle aati hai), jabki filter decide karta hai whether ek item ko loop mein include karna hai, isliye yeh baad wale for se attach hota hai.
Kabhi kabhi list comprehension ke upar generator expression (x for x in it) kyun prefer kiya jaata hai?
Generator lazy hota hai — yeh poori list memory mein build kiye bina ek-ek karke items produce karta hai, ideal jab aap sirf ek baar iterate karte ho ya data bahut bada ho.
[n for n in nums] (koi filter nahi, expr = n) phir bhi useful kyun ho sakta hai?
Yeh nums ki ek shallow copy naye list ke roop mein banata hai, isliye copy ko mutate karne se original affect nahi hota — kabhi kabhi list(nums) se zyada clear hota hai jab doosri logic ke saath combine kiya jaaye.
map()/filter() aur comprehensions overlap kyun karte hain?
Transform wala comprehension map() se milta hai, aur filter wala filter() se milta hai; comprehension sirf dono ko ek readable expression mein combine karta hai, do function calls compose karne ki jagah.
Comprehension ke andar side effects add karna (jaise kisi aur list mein .append) bad style kyun maana jaata hai?
Comprehension ka pura point hai ki cleanly ek value return kare; isme side effects chupaane ka matlab hai ki reader ko pata karne ke liye ise run karna padega, "ek sentence mein padho" wala goal defeat ho jaata hai.

Edge cases

[x for x in []] kya evaluate hota hai?
Empty list []. Empty iterable ka matlab hai loop body kabhi run nahi hoti, isliye kuch kabhi append nahi hota.
[x for x in range(5) if False] kya produce karta hai?
[]. Filter hamesha False hai, isliye har item drop ho jaata hai aur result empty hai — comprehension legally ek empty list build kar sakta hai.
[0 for _ in range(3)] kya build karta hai, aur underscore kyun?
[0, 0, 0]. _ signal karta hai "main loop variable use nahi karta"; expr ek constant 0 hai, isliye yeh sirf har iteration mein value repeat karta hai — list pre-fill karne ka ek common tarika.
Kya [x for x in range(3) if x] mein 0 include hoga?
Nahi — 0 falsy hai, isliye if x ise False maanta hai aur drop kar deta hai. Result hai [1, 2]. Yeh ek classic trap hai: bare if x zero, empty strings, aur None ko filter out kar deta hai.
[1/x for x in [2, 0, 4]] ke saath kya hoga?
Yeh middle item par ZeroDivisionError raise karega. Comprehensions errors skip nahi karte — agar kisi surviving x ke liye expr fail ho, toh poora comprehension abort ho jaata hai. Pehle filter karo: [1/x for x in [2,0,4] if x != 0].
[x for x in "cat"] kya deta hai, kyunki string ek iterable hai?
['c', 'a', 't']. Strings characters ke iterables hain, isliye for x in "cat" ek waqt mein ek character chalta hai — dekho range() and iterables.
[k for k in {"a": 1, "b": 2}] kya produce karta hai, aur kyun?
['a', 'b'] — ek dict iterate karne par uski keys milti hain, values ya pairs nahi. Values ke liye .values() use karo; dono ke liye .items() use karo. Yeh bahut se learners ko trip kar deta hai jo values ki umeed karte hain.

Recall Ek-line self-test

Upar ke answers cover karo. Har item ke liye decide karo kaun sa do ifs mein se involved hai (filter vs ternary), aur expr kab run hota hai filter ke relative. Agar aap in dono axes ko nail kar lo, toh is page ka har trap collapse ho jaata hai.

Connections

  • [[1.2.34 List comprehensions — `[expr for x in iterable if condition]` (Hinglish)|Parent: List comprehensions]]
  • For loops — woh loop jिसमें yeh traps unfold hote hain.
  • Conditional expressions (ternary) — "choose-before" if/else.
  • Dictionary and set comprehensions — same traps {} ke saath.
  • Generator expressions — lazy (...) cousin.
  • map() and filter() — transform aur filter ke functional twins.
  • range() and iterablesfor slot ko kya feed karta hai.