1.2.34 · D3 · 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 note [[1.2.34 List comprehensions — `[expr for x in iterable if condition]`|parent note]] ka "sab kuch dal do" companion hai. Wahan humne [expr for x in iterable if condition] ki shape seekhi thi. Yahan hum ise har tarah ki situation se guzaarenge jo ek comprehension ko face karni pad sakti hai, taaki future mein koi bhi problem surprise na kare.
Hum parent note se aage kuch nahi maante. Agar "iterable" ya "ternary" jaisa koi word aata hai, toh hum use use karte waqt wahan pe seedha explain karte hain.
Examples kaam karne se pehle, aao poore territory ka map banate hain. Ek list comprehension mein teen slots hote hain — expr, for, if — aur har slot kuch "states" mein se ek mein ho sakta hai. Neeche ki table mein har distinct case class listed hai jo yeh topic tumhare saamne rakh sakta hai. Baad ke har example pe us cell ka tag lagega jise woh cover karta hai.
#
Case class
Usmein kya khaas hai
Covered by
A
Transform only (no filter)
Har item bachta hai; sirf expr kaam karta hai
Example 1
B
Filter only (expr = item)
Kuch nahi badlta; items bas rakhe ya drop hote hain
Example 2
C
Transform + filter saath mein
Dono slots active
Example 3
D
Ternary in expr (a if c else b)
Ek value choose karna, if/else for se PEHLE aata hai
Example 4
E
Ternary AND filter ek line mein
Dono ifs present, alag-alag jagah
Example 5
F
Nested for (flatten / grid)
Do loops, outer-to-inner order
Example 6
G
Degenerate input : empty iterable, ya filter sab kuch maar deta hai
Result hai [] — the zero case
Example 7
H
Real-world word problem
English ko comprehension mein translate karna
Example 8
I
Exam twist : nested for + filter jo dono loop variables pe depend karta hai
Evaluation ka order exactly reason karna padega
Example 9
J
Chained filters (ek for ke baad multiple ifs)
Do ifs ek saath AND ki tarah kaam karte hain
Example 10
Ab hum har cell A se J tak cover karenge.
Intuition Cases enumerate kyon karein?
Ek comprehension chhoti lagti hai, isliye log maante hain "ek seekh li toh sab seekh li." Yeh galat hai: empty result , ==do alag ifs, aur nested for ordering== — har ek unhe trip karta hai jo sirf happy path dekh ke aaye hain. Ek baar sabhi das cells dekhna matlab phir koi nayi shape kabhi nahi milegi.
Worked example Pehle paanch whole numbers ke squares
0 2 , 1 2 , 2 2 , 3 2 , 4 2 ki list banao.
Forecast: aage padhne se pehle output list guess karo. (4 2 kya hai?)
Step 1 — iterable chunno. Humein 0 , 1 , 2 , 3 , 4 numbers chahiye. Python mein range(5) exactly yahi produce karta hai (ek iterable = koi cheez jiske upar loop kar sako; dekho range() and iterables ).
Yeh step kyun? for x in iterable slot pehle fill hona chahiye — execution actually isi se shuru hoti hai.
Step 2 — filter decide karo. Hum har number chahte hain, koi drop nahi.
Yeh step kyun? Case A matlab "koi if nahi" — toh hum simply filter slot chhod dete hain.
Step 3 — expr decide karo. Hum square chahte hain, toh expr = x**2 (Python mein ** matlab "ki power").
Yeh step kyun? expr wahi hai jo nayi list mein jaata hai, har item ke liye aakhir mein compute hota hai.
Step 4 — template mein daalo.
squares = [x ** 2 for x in range ( 5 )]
# → [0, 1, 4, 9, 16]
Yeh step kyun? Teeno chosen slots (expr, for, koi if nahi) ab template [expr for x in iterable] mein apni fixed positions pe baith gaye; assemble karna ek mechanical last move hai jo hamare plan ko runnable code mein badalta hai.
Verify: count = 5 items in, 5 items out (transform-only kabhi length nahi badlta). Last wala check karo: 4 2 = 16 . ✓ List hai [ 0 , 1 , 4 , 9 , 16 ] .
Worked example Sirf positive numbers rakho
[3, -1, 4, -5, 9, 0] mein se positives rakho.
Forecast: kaun se numbers bachenge? Kya 0 positive hai?
Step 1 — iterable. List khud: for n in [3, -1, 4, -5, 9, 0].
Yeh step kyun? Items ka source.
Step 2 — filter. "Positive" matlab strictly zero se zyada: if n > 0. Note karo 0 > 0 hai False, toh zero drop ho jaata hai.
Yeh step kyun? Zero boundary exactly wahi jagah hai jahan filters logon ko trip karti hai — ise abhi pin kar do.
Step 3 — expr. Hum items ko unchanged rakhte hain, toh expr = n (bas item khud).
Yeh step kyun? Case B: output expression plain loop variable hai, toh comprehension pure sieve ki tarah kaam karti hai.
Step 4 — assemble.
positives = [n for n in [ 3 , - 1 , 4 , - 5 , 9 , 0 ] if n > 0 ]
# → [3, 4, 9]
Yeh step kyun? Teeno slots (n, for, if n > 0) ko full template [expr for x in iterable if condition] mein daala; assembling prove karta hai ki plan complete aur runnable hai.
Verify: 6 in, 3 out (filters length shrink ya keep karti hain, kabhi grow nahi). Jo drop hue: − 1 , − 5 , 0 — sab n > 0 fail kar rahe hain. ✓
Worked example 0–9 ke even numbers ke squares
0..9 mein se har number ka square nikalo, lekin sirf even wale.
Forecast: das mein se "even" filter survive karke kitne items bachenge?
Step 1 — iterable. range(10) deta hai 0 , 1 , … , 9 .
Yeh step kyun? Problem kehti hai "har number 0..9", aur range(10) exactly 0 se 9 tak produce karta hai — yeh woh source hai jahan se for slot draw karta hai, kuch aur run hone se pehle.
Step 2 — filter. "Even" matlab 2 se divisible. Operator % division ka remainder deta hai, toh x % 2 hoga 0 jab x even ho. Isliye if x % 2 == 0.
Yeh step kyun? % (modulo) "kya yeh divisible hai?" ke liye standard tool hai — yeh exactly "kya bacha?" ka jawab deta hai, aur bacha 0 matlab clean division.
Step 3 — expr. x**2.
Yeh step kyun? Problem har survivor ka square maangti hai, toh output expression jo nayi list mein jaaye woh x**2 hona chahiye — transform sirf filter pass karne waale items pe, aakhir mein run hota hai.
Step 4 — assemble.
result = [x ** 2 for x in range ( 10 ) if x % 2 == 0 ]
# → [0, 4, 16, 36, 64]
Yeh step kyun? Teeno slots ab decide ho gaye, toh hum inhe [expr for x in iterable if condition] mein rakhte hain — assembling woh final mechanical step hai jo transform aur filter ko ek runnable line mein fuse karta hai.
Verify: 0..9 mein even numbers hain 0 , 2 , 4 , 6 , 8 (paanch), squares 0 , 4 , 16 , 36 , 64 . Output mein paanch. ✓
Worked example Negatives ko zero se replace karo (length rakho)
[3, -1, 4, -5] mein se, har negative ko 0 mein badlo lekin har slot rakho .
Forecast: answer kitna lamba hai — 2 ya 4?
Step 1 — pehchano: yeh filter NAHI hai. Hum items drop nahi kar rahe; hum har item ke liye ek value choose kar rahe hain. Iska matlab hai ek conditional expression (ek ternary : dekho Conditional expressions (ternary) ).
Yeh step kyun? Filter vs value-choice comprehension-land mein sabse badi fork hai. Drop karna → filter if for ke baad. Choose karna → ternary for se pehle.
Step 2 — ternary likho. Form hai value_if_true if condition else value_if_false. Yahan: n if n > 0 else 0. Padho ise "jab n > 0 ho toh n do, warna 0 do".
Yeh step kyun? Ek ternary hamesha ek value return karta hai, toh woh legally expr slot mein baith sakta hai.
Step 3 — rakh do (assemble). Kyunki yeh expr hai, yeh for se pehle jaata hai:
clamped = [n if n > 0 else 0 for n in [ 3 , - 1 , 4 , - 5 ]]
# → [3, 0, 4, 0]
Yeh step kyun? Assembling yahan woh jagah bhi hai jahan positioning trap settle hoti hai — ternary expr slot hai, toh yeh for se pehle hona chahiye, mnemonic ke mutabiq "Choose-before, Cut-after".
Verify: length 4 rehti hai (ternary kabhi items drop nahi karta). 3 → 3 , − 1 → 0 , 4 → 4 , − 5 → 0 . ✓
Common mistake Classic swap
[n for n in xs if n > 0 else 0] likhna ek SyntaxError hai. for ke baad filter if ko else rakhne ki ijazat nahi hai. Agar else dikhta hai, toh use expr mein rehna chahiye, for se pehle.
Worked example 1–10 ke numbers mein se, sirf 3 ke multiples rakho, aur har ek ko uske square ya "big" ke roop mein label karo
1..10 mein se 3 ke multiples rakho; har survivor ke liye uska square emit karo agar woh 30 se kam hai, warna string "big".
Forecast: 1..10 mein 3 ke kaun se multiples ke squares 30 se kam hain?
Step 1 — filter (Cut-after). 3 ke multiples: if x % 3 == 0. for ke baad jaata hai.
Yeh step kyun? "Sirf 3 ke multiples rakho" ek dropping decision hai — kuch numbers kabhi list mein enter hi nahi karne chahiye. Drop karna hamesha filter if hota hai, aur filter if hamesha for ke baad jaata hai (mnemonic "Cut-after").
Step 2 — ternary (Choose-before). Har survivor ke liye, x**2 if x**2 < 30 else "big". for se pehle jaata hai.
Yeh step kyun? "Uska square emit karo, warna string big" surviving item ke liye ek value-choice hai, drop nahi. Value-choice ek ternary hai, aur ternary expr mein rehta hai, jo for se pehle baithta hai (mnemonic "Choose-before").
Step 3 — dono assemble karo. Do ifs, do positions:
out = [x ** 2 if x ** 2 < 30 else "big" for x in range ( 1 , 11 ) if x % 3 == 0 ]
# → [9, "big", "big"]
Yeh step kyun? Yeh "dono ifs" wali full shape hai. for ke baad waala decide karta hai kya item enter karta hai; for se pehle waala decide karta hai kya woh ban jaata hai. Assembling prove karta hai ki do ifs ek saath bina clash ke coexist karte hain kyunki woh alag-alag slots occupy karte hain.
Verify: 1..10 mein 3 ke multiples hain 3 , 6 , 9 . Squares: 9 , 36 , 81 . Sirf 9 < 30 , toh → 9 ; 36 aur 81 → "big". Output [ 9 , "big" , "big" ] , length 3. ✓
Worked example Ek 3×2 grid ko ek flat list mein flatten karo
grid = [[1, 2], [3, 4], [5, 6]] → ek flat list.
Forecast: chhe numbers ka order guess karo.
Step 1 — pehle honest nested loop likho.
flat = []
for row in grid: # outer: [1,2], phir [3,4], phir [5,6]
for cell in row: # inner: us row ka har number
flat.append(cell)
Yeh step kyun? Nested-for comprehensions usi order mein padte hain jaise nested loops — pehle outer, phir inner. Loop likhne se order pin ho jaata hai.
Step 2 — collapse karo, loop order rakhte hue (assemble). Rule (parent note ke equivalence law se) yeh hai ki ek comprehension loops ko left-to-right, usi order mein copy karta hai jaise aap unhe nested for statements ke roop mein type karte . Toh outer loop (for row in grid) pehle / leftmost likha jaata hai, aur inner loop (for cell in row) doosra likha jaata hai, exactly jaise woh nest karte hain:
flat = [cell for row in grid for cell in row]
# → [1, 2, 3, 4, 5, 6]
Yeh step kyun? Assembling woh jagah hai jahan ordering law kaata hai: kyunki desugaring ek mechanical left-to-right rewrite hai — har for clause ek loop ban jaata hai usi order mein — leftmost for outermost loop hona chahiye. Inhe swap karna (for cell in row for row in grid) ek NameError raise karta hai, kyunki row use hone se pehle uski loop define nahi hui hoti. Yahi naam-dependency exactly wajah hai jis se assembled order force hota hai.
Neeche ki figure yeh trace karti hai: har grid row (colour-coded) left-to-right flat list mein jaati hai, outer row-loop slow, inner cell-loop fast.
Figure: baaye 3 × 2 grid; coloured arrows har row ke cells (orange = row 0, teal = row 1, plum = row 2) ko daaye single flat list mein le jaate hain, outer-to-inner order mein.
Verify: 3 rows × 2 cells = 6 items. Order figure mein arrows follow karta hai: pehle row [ 1 , 2 ] , toh 1 , 2 , phir 3 , 4 , phir 5 , 6 . ✓
Worked example Empty iterable aur "filter sab kuch maar deta hai"
Do edge cases jinhe zyaadatar log kabhi test nahi karte.
Forecast: kya kuch nahi pe comprehension kya return karta hai? Crash, None, ya []?
Step 1 — empty iterable. range(0) koi bhi item yield nahi karta.
a = [x ** 2 for x in range ( 0 )]
# → []
Yeh step kyun? Agar for kabhi koi x nahi uthata, expr kabhi run nahi hota — aapko empty list milti hai, kabhi error nahi. Yeh safe, graceful base case hai.
Step 2 — filter sab drop kar deta hai. Non-empty source, lekin koi item pass nahi hoti:
b = [n for n in [ 1 , 3 , 5 ] if n % 2 == 0 ]
# → []
Yeh step kyun? Odd numbers kabhi "even" satisfy nahi kar sakte, toh har item drop ho jaati hai. Phir bhi [], error nahi.
Verify: dono empty list [] hain. Ek comprehension hamesha ek list return karta hai (possibly empty); woh kabhi None return nahi karta aur sirf isliye raise nahi karta kyunki rakhne ko kuch nahi hai. ✓
Worked example Tax ke saath prices, lekin sirf affordable items
Ek shop mein prices (₹ mein) hain [100, 250, 40, 999, 60]. 18% tax add karo, lekin sirf woh items include karo jinki pre-tax price ₹200 ya kam ho. Tax-inclusive prices ko whole rupees mein round karo.
Forecast: ₹200 cutoff pe kaun se teen prices bachenge?
Step 0 — tool round() anchor karo. round(value) ek built-in Python function hai jo value ke nearest whole number return karta hai; .5 tie pe yeh nearest even number tak round karta hai (toh round(2.5) hai 2), lekin yahan koi ties nahi aayenge. Example: round(70.8) deta hai 71, round(47.2) deta hai 47.
Yeh step kyun? Use karne se pehle har tool define karna zaroori hai — round wahi hai jo 70.8 ko clean ₹ amount mein badlta hai, aur fractions pe uska exact behaviour answer decide karta hai.
Step 1 — English sentence se slots identify karo.
iterable: for p in [100, 250, 40, 999, 60]
filter: "pre-tax price at most ₹200" → if p <= 200
expr: "18% tax add karo, round karo" → round(p * 1.18)
Yeh step kyun? Word problems solve hote hain har English clause ko ek slot se match karke. "Sirf include karo… if" hamesha filter hai; "compute/transform" hamesha expr hai.
Step 2 — ordering trap note karo. Filter pre-tax p use karta hai, aur yeh expr se pehle run hota hai. Toh hum raw price pe filter karte hain, phir survivors ko tax karte hain — exactly wahi jo sentence kehta hai.
Yeh step kyun? Execution order hai for → if → expr; filter kabhi taxed value nahi dekhta, jo yahan hum chahte hain.
Step 3 — assemble.
final = [ round (p * 1.18 ) for p in [ 100 , 250 , 40 , 999 , 60 ] if p <= 200 ]
# → [118, 47, 71]
Yeh step kyun? Tool anchored aur slots matched hone ke baad, assembling filter aur rounded transform ko us single line mein fuse karta hai jo word problem ka jawab deta hai.
Verify: survivors (≤ 200 ): 100 , 40 , 60 . Taxed: 100 × 1.18 = 118 , 40 × 1.18 = 47.2 → 47 , 60 × 1.18 = 70.8 → 71 . Dropped: 250 , 999 . Units poore time ₹ mein rehte hain. Output [ 118 , 47 , 71 ] . ✓
Worked example Even-sum pairs
Do ranges se, saare pairs (i, j) banao jahan i ho 1..3 mein, j ho 1..3 mein, sirf woh pairs rakhte hue jahan i + j even ho. Product i*j emit karo.
Forecast: nau possible pairs mein se kitne ki sum even hai?
Step 1 — do loops. Outer for i in range(1, 4), inner for j in range(1, 4). Dono dete hain 1 , 2 , 3 .
Yeh step kyun? Do fors = nested loops, outer pehle likha jaata hai (Case F rule), 3 × 3 = 9 candidate pairs deta hai.
Step 2 — filter dono loop variables pe depend karta hai. if (i + j) % 2 == 0. Yeh legal hai — ek filter koi bhi variable use kar sakta hai jo uske left se introduce hua ho.
Yeh step kyun? Subtle exam point: filter innermost loop ke andar evaluate hota hai, jahan dono i aur j known hain, toh woh inhe combine kar sakta hai.
Step 3 — expr. Product i * j.
Yeh step kyun? Problem "product i*j emit karo" maangti hai, toh output expression jo nayi list mein jaaye woh i * j hona chahiye — last mein compute hota hai, sirf un pairs ke liye jo even-sum filter pass kar chuke hain.
Step 4 — assemble.
out = [i * j for i in range ( 1 , 4 ) for j in range ( 1 , 4 ) if (i + j) % 2 == 0 ]
Yeh step kyun? Saare slots ab decide ho gaye (do fors outer-to-inner order mein, ek two-variable filter, ek product expr), toh hum inhe template mein rakhte hain — assembling woh mechanical final move hai jo reasoning ko ek runnable line mein badalta hai.
Step 5 — exact loop order mein trace karo. Outer i slowly move karta hai; har i ke liye inner j 1 , 2 , 3 sweep karta hai. Ek pair sirf tab rakha jaata hai jab i + j even ho:
i = 1 : j = 1 ⇒ sum 2 even ✓ product 1 ; j = 2 ⇒ sum 3 odd ✗; j = 3 ⇒ sum 4 even ✓ product 3 .
i = 2 : j = 1 ⇒ sum 3 odd ✗; j = 2 ⇒ sum 4 even ✓ product 4 ; j = 3 ⇒ sum 5 odd ✗.
i = 3 : j = 1 ⇒ sum 4 even ✓ product 3 ; j = 2 ⇒ sum 5 odd ✗; j = 3 ⇒ sum 6 even ✓ product 9 .
✓ products ko loop order mein padhne se milta hai out = [1, 3, 4, 3, 9].
Verify: 9 mein se 5 pairs bachte hain, aur order outer-i-slow / inner-j-fast follow karta hai: ( 1 , 1 ) , ( 1 , 3 ) , ( 2 , 2 ) , ( 3 , 1 ) , ( 3 , 3 ) → products [ 1 , 3 , 4 , 3 , 9 ] . ✓
Worked example 2 aur 3 dono se divisible numbers
1..20 mein se woh numbers rakho jo even aur 3 se divisible hain, do alag if clauses use karke.
Forecast: 1..20 mein kaun se numbers 2 aur 3 dono se divisible hain?
Step 1 — iterable. range(1, 21) deta hai 1 , 2 , … , 20 .
Yeh step kyun? Woh source jahan se for slot draw karta hai.
Step 2 — pehchano ki filters chain kiye ja sakte hain. Python ek single for ke baad ek se zyada filter if allow karta hai, back-to-back bina kisi and aur bina kisi else ke: ... if cond1 if cond2. Yeh cond1 and cond2 ki tarah behave karte hain — ek item sirf tab bachta hai jab har clause True ho.
Yeh step kyun? Yeh valid "multiple filter" case hai. Do ifs ek row mein syntax error nahi hain (unlike if...else after for); yeh sirf chained filtering hai, left-to-right evaluate hoti hai.
Step 3 — dono filters likho. Even: if x % 2 == 0. 3 se divisible: if x % 3 == 0.
Yeh step kyun? Har condition ek alag clause hai; inhe chain karne ka matlab hai item ko pehla clear karna hoga phir doosra test hoga.
Step 4 — assemble.
out = [x for x in range ( 1 , 21 ) if x % 2 == 0 if x % 3 == 0 ]
# → [6, 12, 18]
Yeh step kyun? expr = x aur do chained filters decide hone ke baad, assembling inhe [expr for x in iterable if cond1 if cond2] mein rakhta hai — mechanical final step jo dikhata hai ki chained ifs single for ke baad side by side rehte hain.
Verify: 2 aur 3 dono se divisible matlab 6 se divisible. 1..20 mein 6 ke multiples: 6 , 12 , 18 . Output [ 6 , 12 , 18 ] . ✓ (Equivalent one-filter form if x % 2 == 0 and x % 3 == 0 same list deta hai.)
Recall Kaun sa cell kaun sa tha?
Match example → matrix cell.
Example 4 (n if n>0 else 0) kaun sa case cover karta hai? ::: Case D — ternary in expr, if/else for se pehle.
Example 7 kaun sa case cover karta hai? ::: Case G — degenerate inputs, result hai [].
Example 9 ka filter dono i aur j use karta hai — kya yeh legal hai? ::: Haan; ek filter koi bhi variable use kar sakta hai jo uske left se introduce hua ho (Case I).
Example 8 mein, filter pre-tax price dekhta hai ya post-tax? ::: Pre-tax — filter expr se pehle run hota hai.
Ek for ke baad do ifs ek row mein allowed hain? ::: Haan — chained filters (Case J), and ki tarah behave karte hain.
Mnemonic Das-cell checklist
Ek comprehension ship karne se pehle poochho: transform? filter? dono? ternary? nested? chained filters? kya yeh empty ho sakta hai? Agar har ek ka jawab de sako, tumne A–J cover kar liya.
For loops — har example pehle honest loop ke roop mein likha gaya, phir collapse kiya gaya.
Conditional expressions (ternary) — Examples 4 aur 5 mein a if c else b.
map() and filter() — Examples 1–2 disguise mein map/filter hain.
Dictionary and set comprehensions — same cells, alag brackets.
Generator expressions — results lazily paane ke liye [] ki jagah () use karo.
range() and iterables — lagbhag har example mein for slot feed karta hai.
Neeche ka diagram pure recap hai: central node scenario matrix hai, aur har branch ek case class (A–J) hai us example ke saath jo use cover karta hai. Ise checklist ki tarah use karo — agar tum har branch ka trick naam le sako, tumne poora territory cover kar liya.
C transform plus filter - Ex3
E ternary and filter - Ex5