Question bank — Nested data structures — list of dicts, dict of lists
1.2.26 · D5· Coding › Introduction to Programming (Python) › Nested data structures — list of dicts, dict of lists
Shuru karne se pehle, picture yahan seedhi bana lo taaki kuch bhi baad ke liye na chhodna pade. Dono structures same grid of cells store karte hain. Farq sirf itna hai ki pehle kaun sa axis slice karte ho:

Figure dekho: left mein, ek List of Dicts (LoD) ko row cards ki stack ki tarah draw kiya gaya hai — har card ek dict hai {name, age, marks}. Right mein, ek Dict of Lists (DoL) ko side-by-side column strips ki tarah draw kiya gaya hai — har strip ek list hai. Coloured arrows follow karo: single cell "Ravi's marks = 73" LoD mein students[1]["marks"] par aur DoL mein students["marks"][1] par milti hai. Dono index paths cross over karte hain — wahi crossing transpose hai.
True or false — justify
Har item ek statement hai. True/false decide karo, phir reason do.
LoD aur DoL bilkul same information store kar sakte hain.
students[0]["name"] aur students["name"][0] hamesha same value return karte hain, structure chahe kuch bhi ho.
[i][c], DoL ke liye [c][i]. Doosra form error raise karta hai, isliye ye interchangeable nahi hain.LoD mein outer container ka list hona matlab yeh hai ki pehle integer se index karna zaroori hai.
DoL mein har column-list ki same length honi chahiye.
dol = lod2dol(lod) ke baad back = dol2lod(dol) karne par, back == lod True hai lekin back is lod False hai.
== contents compare karta hai (equal cells → equal), isliye pass ho jaata hai; is identity compare karta hai (memory mein same object), aur back ek freshly built list hai, isliye is fail hota hai. Round-tripping value preserve karta hai, identity nahi.LoD→DoL→LoD round-tripping tab bhi data preserve karta hai jab kuch rows mein keys missing hon.
None) se fill karta hai, isliye rebuilt LoD mein waise keys aa jaati hain jo original mein nahi thi — ab == bhi fail ho jaata hai, sirf is nahi.Jab rows bahut zyada hon toh DoL equivalent LoD se kam memory use karta hai.
DoL mein naya record utni aasani se append kar sakte ho jitna LoD mein.
for s in students: LoD mein rows iterate karta hai aur DoL mein columns.
Modern Python (3.7+) mein DoL ki keys iterate karne par random order mein aati hain.
Spot the error
Har line code describe karti hai. Batao kya toot ta hai aur kyun.
students["name"] jahan students ek list of dicts hai.
TypeError raise karta hai. Tumne LoD par DoL access mix kar di — students[0]["name"] use karo.students[0] jahan students ek dict of lists hai jisme string keys hain.
KeyError: 0 — dict mein koi key 0 nahi hai; uski keys field names hain jaise "name". Pehle students["name"] use karo.dol = dict.fromkeys(["name","age"], []) phir dol["name"].append("Asha") — object IDs trace karo.
id(dol["name"]) == id(dol["age"]) True hai: dono keys fromkeys dwara bani ek hi list ko point kar rahi hain, isliye append ke baad dono mein ["Asha"] dikhega. Minimal proof:>>> dol = dict.fromkeys(["name","age"], [])>>> dol["name"].append("Asha")>>> dol → {'name': ['Asha'], 'age': ['Asha']}. Fix karo {c: [] for c in cols} se, jahan har [] apna fresh object hai jiska apna id hai — dekho Mutable vs Immutable.{k: [row[k] for row in lod] for k in lod[0]} jab ek row {"name":"Ravi"} ho (koi "marks" nahi).
KeyError: "marks" aayega. Comprehension yeh maan leti hai ki har row lod[0] ki keys share karti hai. Default ke liye row.get(k) use karo.for s in students: students.remove(s) se LoD clear karna.
students = [s for s in students if s["marks"] >= 40], sirf wahi rows rakho jinka condition sahi ho (yahan, pass marks) instead of in-place delete karne ke.avg = sum(students["marks"]) ek list of dicts par.
students["marks"] pehle hi TypeError se fail ho jaata hai (list ko string se index kiya). Column math tabhi directly kaam karta hai jab column already built ho, ya DoL mein seedha.n = len(students) ko dict of lists ki row count ke roop mein use karna.
len(students) columns count karta hai (keys ki sankhya), rows nahi. Row count hai len(students[any_key]) — ek column ki length.row["age"] += 5 andar for row in students jahan students ek DoL hai.
row ek string key hai jaise "age", dict nahi, isliye row["age"] TypeError raise karta hai. Dict iterate karne par keys milti hain — kisi cell ko touch karne ke liye students["age"][i] use karo.Why questions
Reason answer karo, sirf ek fact nahi.
DoL column average compute karne mein kyun jeet ta hai?
sum(col)/len(col) seedha run hota hai — records mein se gather karne ke liye pehle comprehension ki zaroorat nahi.LoD poora record add ya delete karne mein kyun jeet ta hai?
append (add) ya list-filtering (remove) sirf ek object ko touch karta hai, har column ko nahi.Dono forms ke beech indices order kyun swap ho jaata hai ([i][c] vs [c][i])?
LoD JSON from an API ke saath naturally kyun match karta hai?
for x in students se DoL iterate karna beginners ko kyun surprise karta hai?
Shared-list bug sirf dict.fromkeys(cols, []) ke saath kyun appear karta hai, dict comprehension ke saath nahi?
fromkeys [] ko ek baar evaluate karta hai aur har key ko us ek object ki taraf point karta hai; comprehension {c: [] for c in cols} har iteration par [] fresh run karta hai, independent lists deta hai.LoD→DoL conversion mein keys carefully collect kyun karni padti hain jab rows alag ho sakti hain?
lod[0] ki keys par trust karo toh baaki rows ke paas jo fields hain woh miss ho jaate hain; safe key set hai {k for row in lod for k in row} sab rows par.Pandas DataFrame ko "turbocharged DoL" kyun kaha jaata hai?
Edge cases
Boundary aur degenerate inputs — woh scenarios jo log bhool jaate hain.
Ek empty LoD []: lod[0] kya karta hai, aur uski keys kaise milti hain?
lod[0] IndexError raise karta hai (koi row 0 nahi) aur koi keys padhne ko hain hi nahi — empty LoD ka koi schema nahi hota. lod[0] touch karne se pehle if lod: se guard karo.Ek empty DoL {}: isme kitni rows hain?
len(dol) 0 hai (zero columns), aur row count tab tak unknowable hai jab tak kam se kam ek key exist na kare.LoD par students[-1] vs DoL par students[-1] — har ek ka kya matlab hai?
-1 last row hai (valid, students[len-1]). DoL par outer container ek dict hai, isliye -1 ko key ki tarah treat kiya jaata hai; jab tak literally -1 naam ki key exist na kare, KeyError raise hoga. Negative indexing sirf list layer par kaam karti hai.students[1:3] (ek slice) LoD par vs DoL par — kaun sa kaam karta hai?
TypeError raise hota hai — dicts ko start:stop se slice nahi kar sakte. DoL mein rows slice karne ke liye har column slice karna padega: {c: students[c][1:3] for c in students}.Ek DoL jahan columns ki alag lengths hain ("name" len 3, "age" len 2): kya row 2 valid hai?
"name" ke liye exist karta hai; dol["age"][2] poochh ne par IndexError aayega. Structure malformed hai — har column ka row count same hona chahiye.Ek LoD jahan row 0 mein extra keys hain jo baaki rows mein nahi hain: kya {k: [row[k] ...] for k in lod[0]} kaam karta hai?
KeyError raise ho jaata hai. .get(k) ya full key set use karo.Sirf ek record wala LoD [{"a":1}]: kya yeh valid LoD hai, aur iska DoL?
{"a":[1]} — har column ek length-1 list ban jaati hai. Transpose relationship phir bhi hold karta hai.Sirf ek column wala DoL {"a":[1,2,3]}: iska LoD form kya hai?
[{"a":1},{"a":2},{"a":3}] — teen rows, har ek ek single-field dict. Row count single column ki length se aaya.Rows mein duplicate field values (do students ka naam "Asha") — kya koi bhi structure toot ta hai?
Ek field value jo khud ek list hai (jaise LoD mein "marks":[88,73] har student ke liye): kya access badal jaata hai?
students[0]["marks"] phir bhi woh inner list return karta hai; bas ek level aur neeche index karna padta hai (students[0]["marks"][1]) kisi element tak pahunchne ke liye. Nesting cleanly compose hoti hai.Connections
- Lists — integer-indexed container jo LoD ke outer aur DoL ke inner mein hai
- Dictionaries — key→value lookup jo dono ko power deta hai
- List Comprehensions — transpose engine aur ragged-key traps
- JSON and APIs — kyun list-of-dicts common wire format hai
- Pandas DataFrame — column-first storage, DoL ko production tak le jaana
- Loops and Iteration — kyun dict vs list iterate karna surprise karta hai
- Mutable vs Immutable — shared-inner-list bug ki root cause