Quiz 2

Week 6: Dictionaries

2333 words
12 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Week 6: Dictionaries > **BSCS1001 — IIT Madras BS Degree** **Prerequisite:** Week 5 (Lists) **Cross-links:** BSCS1002-Python (Week 8 — Dictionaries), BSCS2002-PDSA (Week 3 — Map ADT) ## 1. Motivation: Beyond Lists Lists are great for sequences, but they have a limitation: **you can't quickly find an element by its...

Week 6: Dictionaries

BSCS1001 — IIT Madras BS Degree Prerequisite: Week 5 (Lists) Cross-links: BSCS1002-Python (Week 8 — Dictionaries), BSCS2002-PDSA (Week 3 — Map ADT)

1. Motivation: Beyond Lists

Lists are great for sequences, but they have a limitation: you can't quickly find an element by its value.
ProblemWith ListWith Dictionary
"What is Alice's Chemistry mark?"Scan the whole list to find AlicechemMarks["Alice"] — instant!
"Count students per city"Build multiple lists, nested searchesUse city name as key, count as value
"Find duplicates by birthday"Nested iteration (O(N²))Dictionary lookup (O(N))
Real-world analogy: A list is like a row of lockers numbered 0, 1, 2... You must walk down the row to find something. A dictionary is like a phonebook — you look up the name (key) and instantly get the number (value).

2. What is a Dictionary?

A dictionary stores key-value pairs. You provide a key, and the dictionary returns the associated value.

Syntax

pseudo
// Creating a dictionary
d = {}
// Adding key-value pairs
d["Rahul"] = 92
d["Ritika"] = 89
// Accessing values
marks = d["Rahul"]      // marks = 92

Visual Representation

(Diagram)

Key Properties

PropertyDescription
Key-value pairsEach entry maps a key to a value
Unique keysEach key appears at most once
UnorderedKeys are not stored in any particular order
Random accessGet any value instantly by key
DynamicCan add and remove keys

Dictionary vs Record

AspectRecordDictionary
FieldsFixed at design timeDynamic (add any key)
Field namesKnown in advanceCan be data values
SchemaRigidFlexible
ExampleX.Name, X.Mathsd["Rahul"], d["Ritika"]

3. Dictionary Operations

Core Operations

OperationSyntaxExampleDescription
Create emptyd = {}marks = {}New empty dictionary
Assign valued[key] = valued["Rahul"] = 92Creates or updates entry
Get valued[key]m = d["Rahul"]Returns value for key
Check keyisKey(d, k)if isKey(d, "Rahul")True if key exists
List keyskeys(d)for k in keys(d)List of all keys
Delete key(see below)Remove a key-value pair

Assigning Values

pseudo
// First assignment — creates the entry
chemMarks["Rahul"] = 92
// Re-assignment — updates the value
chemMarks["Rahul"] = 95    // Now Rahul's mark is 95
// Incrementing a value
chemMarks["Rahul"] = chemMarks["Rahul"] + 5  // Now 100

Keys Must Be Unique

pseudo
d = {}
d["Alice"] = 85
d["Alice"] = 90    // Overwrites! Now d["Alice"] = 90

Common Gotcha: Key Doesn't Exist

python
d = {"Rahul": 92}
print(d["Ritika"])    // ERROR! "Ritika" is not a key
Always check with isKey before accessing:
python
if (isKey(d, "Ritika")) {
    print(d["Ritika"])
}
else {
    print("Key not found")
}

4. Building Dictionaries

Pattern: Collect Data from Dataset

pseudo
d = {}
while (Table 1 has more rows) {
    Read the first row X in Table 1
    key = some field of X
    value = some other field of X
    d[key] = value
    Move X to Table 2
}

Example: Chemistry Marks Dictionary

pseudo
chemMarks = {}
while (Table 1 has more rows) {
    Read the first row X in Table 1
    name = X.Name
    marks = X.ChemistryMarks
    chemMarks[name] = marks
    Move X to Table 2
}
Dataset:
NameChemistry
Rahul92
Ritika89
Amit78
Result: chemMarks = {"Rahul": 92, "Ritika": 89, "Amit": 78}

Example: Counting with Dictionaries

sql
// Count how many students from each city
cityCount = {}
while (Table 1 has more rows) {
    Read the first row X in Table 1
    city = X.City
    if (isKey(cityCount, city)) {
        cityCount[city] = cityCount[city] + 1
    }
    else {
        cityCount[city] = 1
    }
    Move X to Table 2
}
Tracing with dataset [Chennai, Mumbai, Chennai, Delhi, Chennai]:
CardCityisKey?cityCount After
1Chennai❌ New{"Chennai": 1}
2Mumbai❌ New{"Chennai": 1, "Mumbai": 1}
3Chennai✅ Yes{"Chennai": 2, "Mumbai": 1}
4Delhi❌ New{"Chennai": 2, "Mumbai": 1, "Delhi": 1}
5Chennai✅ Yes{"Chennai": 3, "Mumbai": 1, "Delhi": 1}
Final: {"Chennai": 3, "Mumbai": 1, "Delhi": 1}

5. Processing Dictionaries

Iterating Through Keys

pseudo
foreach k in keys(d) {
    // Do something with d[k]
}

Example: Compute Average

pseudo
total = 0
count = 0
foreach k in keys(chemMarks) {
    total = total + chemMarks[k]
    count = count + 1
}
average = total / count

Example: Find Max Value

pseudo
maxMark = 0
topStudent = ""
foreach k in keys(chemMarks) {
    if (chemMarks[k] > maxMark) {
        maxMark = chemMarks[k]
        topStudent = k
    }
}

Example: Filter Students Above Threshold

pseudo
above80 = []
foreach k in keys(chemMarks) {
    if (chemMarks[k] > 80) {
        above80 = above80 ++ [k]
    }
}

6. isKey Operation

What isKey Does

isKey(d, k) returns True if k is a key in dictionary d, False otherwise.

How isKey Works (Conceptual)

pseudo
Procedure isKey(d, k)
    found = False
    foreach key in keys(d) {
        if (key == k) {
            found = True
            exitloop
        }
    }
    return(found)
End isKey
Important: In our course, we assume isKey is provided as a built-in operation that works in constant time (instant lookup), not by scanning all keys.

Typical Usage Pattern

pseudo
// Add to count if key exists, otherwise create
if (isKey(runs, "Kohli")) {
    runs["Kohli"] = runs["Kohli"] + score
}
else {
    runs["Kohli"] = score
}

7. Birthday Paradox with Dictionaries

This is the most elegant solution — much better than nested iterations or binning.

Algorithm

pseudo
Procedure FindSharedBirthdays() {
    birthdays = {}
    duplicates = {}
    while (Table 1 has more rows) {
        Read the first row X in Table 1
        dob = X.Dob
        seqno = X.SeqNo
        if (isKey(birthdays, dob)) {
            // This birthday already seen — mark as duplicate
            duplicates[dob] = True
            // Store student under this birthday
            birthdays[dob][seqno] = True
        }
        else {
            // First time seeing this birthday
            birthdays[dob] = {}
            birthdays[dob][seqno] = True
        }
        Move X to Table 2
    }
    return(duplicates)
End FindSharedBirthdays

How It Works (with Nested Dictionary)

The birthdays dictionary maps: birthday → {student IDs}
pseudo
birthdays = {
    45:  {101: True, 103: True},    // Two students born on day 45
    120: {102: True, 105: True},    // Two students born on day 120
    200: {104: True}                 // One student born on day 200
}
The duplicates dictionary just tracks which birthdays have >1 student.

Tracing

Dataset:
SeqNoDOB
10145
102120
10345
104200
105120
RowSeqNoDOBisKey?birthdaysduplicates
110145{45: {101: True}}{}
2102120{45: {101}, 120: {102}}{}
310345{45: {101, 103}, 120: {102}}{45: True}
4104200{..., 200: {104}}{45: True}
5105120{..., 120: {102, 105}}{45: True, 120: True}
Result: Duplicates found for DOBs 45 and 120.

Complexity: O(N) — Linear!

No nested iteration needed! Just one pass through the data. This is the power of dictionaries.

8. Dictionary Applications

Customer Spending Analysis

pseudo
// Build dictionary: customer → total spending
spending = {}
while (Table 1 has more rows) {
    Read the first row X in Table 1
    customer = X.CustomerName
    amount = X.Amount
    if (isKey(spending, customer)) {
        spending[customer] = spending[customer] + amount
    }
    else {
        spending[customer] = amount
    }
    Move X to Table 2
}

Pronoun Resolution

Track nouns and pronouns by their position, then match them:
pseudo
partOfSpeech = {}
partOfSpeech["Noun"] = []
partOfSpeech["Pronoun"] = []
while (Table 1 has more rows) {
    Read the first row X in Table 1
    if (X.PartOfSpeech == "Noun") {
        partOfSpeech["Noun"] = partOfSpeech["Noun"] ++ [X.SerialNo]
    }
    if (X.PartOfSpeech == "Pronoun") {
        partOfSpeech["Pronoun"] = partOfSpeech["Pronoun"] ++ [X.SerialNo]
    }
    Move X to Table 2
}
// Now match each pronoun to nearest preceding noun
matchD = {}
foreach p in partOfSpeech["Pronoun"] {
    matched = -1
    foreach n in partOfSpeech["Noun"] {
        if (n < p) {
            matched = n
        }
        else {
            exitloop    // Nouns are sorted, no need to continue
        }
    }
    matchD[p] = matched
}

Food Items Analysis

pseudo
// Count food items per customer
foodD = {}
while (Table 1 has more rows) {
    Read the first row X in Table 1
    customer = X.CustomerName
    items = X.Items
    for each row in items {
        if (row.Category == "Food") {
            if (isKey(foodD, customer)) {
                foodD[customer] = foodD[customer] + 1
            }
            else {
                foodD[customer] = 1
            }
        }
    }
    Move X to Table 2
}

9. Comparison: List vs Dictionary

List vs Dictionary

AspectListDictionary
AccessBy position (index)By key
OrderMaintains insertion orderUnordered
Speed: lookup by valueO(N) — must scanO(1) — instant
Speed: iterationO(N) — linearO(N) — linear
Keys must be unique?N/A (positions are unique)Yes
Use caseSequences, ordered dataLookups, mappings, counting

When to Use What

(Diagram)

Converting Between List and Dictionary

pseudo
// List of keys → dictionary with True values
students = ["Rahul", "Ritika", "Amit"]
studentDict = {}
foreach s in students {
    studentDict[s] = True
}
// Now: if (isKey(studentDict, "Rahul")) is instant

10. Practice Questions

Basic Questions

Q1. What is a dictionary? What are its two main components?
Show Answer
A dictionary stores key-value pairs. Each entry has a key (used to look up) and a value (the data stored). Keys must be unique. Q2. What does isKey(d, k) do? Show Answer
isKey(d, k) checks if k exists as a key in dictionary d. It returns True if the key exists, False otherwise. Q3. Write pseudocode to create a dictionary that stores students' ages (name → age). Show Answer
pseudo
ages = {}
ages["Alice"] = 20
ages["Bob"] = 22
ages["Charlie"] = 19
Q4. What is the advantage of using a dictionary over nested iterations for finding shared birthdays?
Show Answer
With nested iterations, finding shared birthdays requires O(N²) comparisons. With a dictionary, we can do it in O(N) — a single pass through the data. Dictionaries provide instant (O(1)) lookup by key, eliminating the need for pairwise comparisons.

Intermediate Questions

Q5. Trace this pseudocode:
pseudo
d = {}
d["x"] = 10
d["y"] = 20
d["x"] = d["x"] + 5
d["z"] = d["x"] + d["y"]
What is d at the end?
Show Answer
StepStatementd After
1d = {}{}
2d["x"] = 10{"x": 10}
3d["y"] = 20{"x": 10, "y": 20}
4d["x"] = 10 + 5 = 15{"x": 15, "y": 20}
5d["z"] = 15 + 20 = 35{"x": 15, "y": 20, "z": 35}
Final: {"x": 15, "y": 20, "z": 35} Q6. Write pseudocode to find the student with the highest Chemistry mark using a dictionary. Show Answer
pseudo
chemMarks = {"Rahul": 92, "Ritika": 89, "Amit": 78, "Priya": 95}

maxMark = 0
topStudent = ""
foreach k in keys(chemMarks) {
    if (chemMarks[k] > maxMark) {
        maxMark = chemMarks[k]
        topStudent = k
    }
}
// topStudent = "Priya", maxMark = 95
Q7. Explain the difference between a record's field access (X.Name) and a dictionary's key access (d["Name"]).
Show Answer
  • Record field: X.Name — the field name is fixed at design time. You must know the field name when writing the code.
  • Dictionary key: d["Name"] — the key can be any value, including data read at runtime. You can use variables as keys.
Dictionaries are more flexible because keys can be computed dynamically. Q8. What happens if you access a key that doesn't exist in a dictionary? How do you avoid this? Show Answer
Accessing a non-existent key causes an error. To avoid this, always check with isKey first:
pseudo
if (isKey(d, someKey)) {
    value = d[someKey]    // Safe!
}
else {
    // Handle missing key
}

Advanced Questions

Q9. Write a procedure that takes two dictionaries and returns a new dictionary containing keys present in BOTH. The values should be from the first dictionary.
Show Answer
pseudo
Procedure DictIntersection(d1, d2) {
    result = {}
    foreach k in keys(d1) {
        if (isKey(d2, k)) {
            result[k] = d1[k]
        }
    }
    return(result)
End DictIntersection

// Example:
// d1 = {"a": 1, "b": 2, "c": 3}
// d2 = {"b": 20, "c": 30, "d": 40}
// Result: {"b": 2, "c": 3}
Q10. Use a dictionary to find the most frequently occurring word in a paragraph.
Show Answer
pseudo
wordCount = {}
while (Pile 1 has more cards) {
    Pick a card X
    word = X.Word

    if (isKey(wordCount, word)) {
        wordCount[word] = wordCount[word] + 1
    }
    else {
        wordCount[word] = 1
    }
}

// Find most frequent
maxCount = 0
mostFreq = ""
foreach w in keys(wordCount) {
    if (wordCount[w] > maxCount) {
        maxCount = wordCount[w]
        mostFreq = w
    }
}
Q11. Compare the three approaches to the birthday paradox: nested iteration, binning, and dictionary. Which is best and why?
Show Answer
ApproachComplexityEaseBest For
Nested iterationO(N²)SimpleSmall N (< 100)
BinningO(N²/K)ModerateMedium N, natural bins
DictionaryO(N)EasyAny N, especially large
Best: Dictionary approach. It's simple, requires only one pass through the data (O(N)), and doesn't need pre-defined bins or nested loops. The key insight is using the birthday as the key and checking for duplicates via isKey. Q12. Write pseudocode to create a dictionary where each key maps to a LIST of values (e.g., students per city). Show Answer
pseudo
cityStudents = {}
while (Table 1 has more rows) {
    Read the first row X in Table 1
    city = X.City
    student = X.Name

    if (isKey(cityStudents, city)) {
        // Append to existing list
        cityStudents[city] = cityStudents[city] ++ [student]
    }
    else {
        // Create new list
        cityStudents[city] = [student]
    }
    Move X to Table 2
}

// Result: {"Chennai": ["Rahul", "Priya"], "Mumbai": ["Amit"]}

📚 Cross-References

CourseTopicConnection
BSCS1002 (Python)Week 8 — DictionariesPython dict, keys(), in
BSCS2002 (PDSA)Week 3 — Map ADTDictionary as abstract data type
BSCS2002 (PDSA)Week 7 — HashingHow dictionaries achieve O(1) lookup

Quiz Tip: Birthday paradox with dictionaries is a classic — understand it thoroughly! Join Discord PreviousInsertion SortNextDictionary Applications
Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.