Bytebook Compiler

Data Structures in Python

Dictionaries

Key–value storage with O(1) lookup: creating and updating dicts, safe access with get, looping over keys, values and items, nesting, counting and grouping.

3 min read6 runnable examples4-question quiz

A dictionary (dict) maps keys to values. Lookup by key is O(1) on average because a dict is a hash table. Since Python 3.7, dicts remember insertion order.

Python
student = {"name": "Asha", "roll": 101, "cgpa": 9.1}
print(student["name"])
student["cgpa"] = 9.3              # update
student["city"] = "Pune"           # add a new key
del student["roll"]                # remove
print(student)
print(len(student), "city" in student, "roll" in student)
Output
Asha
{'name': 'Asha', 'cgpa': 9.3, 'city': 'Pune'}
3 True False

Safe access

d[key] raises KeyError if the key is missing. get returns a default instead:

Python
prices = {"pen": 10, "notebook": 45}
print(prices.get("pen"), prices.get("eraser"), prices.get("eraser", 0))
stock = prices.setdefault("ruler", 25)     # insert only if missing
print(stock, prices)
print(prices.pop("pen"), prices)
Output
10 None 0
25 {'pen': 10, 'notebook': 45, 'ruler': 25}
10 {'notebook': 45, 'ruler': 25}

Looping

Python
marks = {"Asha": 91, "Ravi": 78, "Meera": 85}
for name in marks:                     # keys
    print(name, end=" ")
print()
print(list(marks.values()), sum(marks.values()))
for name, m in marks.items():          # key-value pairs
    print(f"{name:6} {m} {'distinction' if m >= 85 else ''}")
topper = max(marks, key=marks.get)
print("Topper:", topper)
print(sorted(marks.items(), key=lambda kv: kv[1], reverse=True))
Output
Asha Ravi Meera 
[91, 78, 85] 254
Asha   91 distinction
Ravi   78 
Meera  85 distinction
Topper: Asha
[('Asha', 91), ('Meera', 85), ('Ravi', 78)]

Counting and grouping

Python
text = "the quick brown fox jumps over the lazy dog the end"
freq = {}
for word in text.split():
    freq[word] = freq.get(word, 0) + 1
print(freq["the"], freq["fox"])

from collections import Counter, defaultdict
c = Counter(text.split())
print(c.most_common(2))

by_length = defaultdict(list)          # missing keys start as []
for word in set(text.split()):
    by_length[len(word)].append(word)
print({k: sorted(v) for k, v in sorted(by_length.items())})
Output
3 1
[('the', 3), ('quick', 1)]
{3: ['dog', 'end', 'fox', 'the'], 4: ['lazy', 'over'], 5: ['brown', 'jumps', 'quick']}

Nested dictionaries

Python
course = {
    "CSE101": {"name": "Programming in C", "credits": 4, "students": ["Asha", "Ravi"]},
    "CSE102": {"name": "Data Structures", "credits": 4, "students": ["Meera"]},
}
course["CSE102"]["students"].append("Kiran")
for code, info in course.items():
    print(f"{code}: {info['name']} ({info['credits']} credits) - {len(info['students'])} students")
Output
CSE101: Programming in C (4 credits) - 2 students
CSE102: Data Structures (4 credits) - 2 students

Building and merging

Python
keys = ["a", "b", "c"]
d1 = dict(zip(keys, [1, 2, 3]))
d2 = {"c": 30, "d": 40}
print(d1 | d2)                      # merge (Python 3.9+); right side wins on clashes
d1.update(d2)
print(d1)
squares = {n: n * n for n in range(1, 6)}
print(squares)
inverted = {v: k for k, v in squares.items()}
print(inverted[16])
Output
{'a': 1, 'b': 2, 'c': 30, 'd': 40}
{'a': 1, 'b': 2, 'c': 30, 'd': 40}
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
4
Operation Average cost
d[k], d[k] = v, k in d, del d[k] O(1)
loop over all items O(n)

Test yourself

4 questions · pick an answer to check it instantly

  1. 1

    What does {"a": 1}.get("b", 0) return?

  2. 2

    How do you loop over keys and values together?

  3. 3

    What is printed?

    Python
    d = {"x": 1, "y": 2}
    d["x"] = 5
    print(len(d), d["x"])
  4. 4

    Why is key in my_dict fast?