Lesson 9 of 12

Python Dictionaries and Sets

Lists are great when position matters: first, second, third. Often, though, you want to look a value up by a name: the price of “masala dosa”, the phone number of “Revathi”, the pincode of “Karaikal”. A dictionary (dict) stores exactly that kind of data as key–value pairs. A set is a related collection that keeps only unique values. Python dictionaries and sets both build on Python Lists and Tuples.

Creating and reading a dictionary

Write a dictionary with curly braces, a colon between each key and its value, and commas between pairs. Keys are usually strings, but any unchangeable value (numbers, tuples) can be a key. Each key appears only once. Read a value with square brackets and the key.

menu = {"idli": 40, "masala dosa": 90, "pongal": 70}

print(menu["pongal"])
print(len(menu))
print("vada" in menu)

print(menu.get("vada"))
print(menu.get("vada", "not on the menu"))

menu["vada"] = 35
menu["idli"] = 45
del menu["pongal"]
print(menu)
Output
70
3
False
None
not on the menu
{'idli': 45, 'masala dosa': 90, 'vada': 35}
  • menu["vada"] raises a KeyError if the key is missing. menu.get("vada") returns None instead, or the default you pass as the second argument.
  • Assigning to a key adds the pair if it is new, or replaces the value if the key already exists.
  • del menu[key] removes a pair; menu.pop(key) removes it and returns the value.
  • in checks the keys, not the values.

Since Python 3.7, dictionaries remember the order in which keys were added, so printing or looping gives a predictable order.

Looping over Python dictionaries

A for loop over a dictionary gives you its keys. Usually you want both key and value, which .items() provides. .keys() and .values() give just one side; sum(menu.values()), for example, adds up every price.

stock = {"Ponni rice (kg)": 120, "Toor dal (kg)": 0, "Groundnut oil (L)": 35}

for item, qty in stock.items():
    status = "OUT OF STOCK" if qty == 0 else qty
    print(f"{item:<20} {status}")

votes = ["Chennai", "Madurai", "Chennai", "Trichy", "Chennai", "Madurai"]
counts = {}
for city in votes:
    counts[city] = counts.get(city, 0) + 1
print(counts)

student = {
    "name": "Ishaan",
    "marks": {"maths": 91, "science": 84},
    "clubs": ["robotics", "quiz"],
}
print(student["marks"]["science"])
print(student["clubs"][0])
Output
Ponni rice (kg)      120
Toor dal (kg)        OUT OF STOCK
Groundnut oil (L)    35
{'Chennai': 3, 'Madurai': 2, 'Trichy': 1}
84
robotics

The counting pattern in the middle, counts[key] = counts.get(key, 0) + 1, is worth memorising. It starts each new key at zero and adds one every time the key appears. The standard library also has collections.Counter, which does the same job in one line.

Nested data

A dictionary value can be another dictionary or a list, as in student above. This is how most real data looks, including the JSON that web APIs send, which you will save and load in Python File Handling. Read nested values one step at a time: student["marks"] is a dictionary, so student["marks"]["science"] reaches inside it.

Dictionary comprehensions

Just like lists, Python dictionaries can be built in one line: {key_expr: value_expr for item in items}. For example, {name: len(name) for name in names} maps each name to its length, and {item: price * 1.05 for item, price in menu.items()} builds a new menu with a 5% price rise.

Sets

A set is an unordered collection of unique values, written with curly braces: {1, 2, 3}. Adding a value that is already present does nothing. Sets are perfect for removing duplicates and for very fast in checks. To make an empty set, write set(), because {} creates an empty dictionary.

OperationOperatorMethodResult contains
Uniona | ba.union(b)Everything in either set
Intersectiona & ba.intersection(b)Only what is in both
Differencea - ba.difference(b)In a but not in b
Symmetric differencea ^ ba.symmetric_difference(b)In one set but not both
roll_numbers = [12, 7, 12, 3, 7, 21]
unique = set(roll_numbers)
print(unique)
print(len(unique))

cricket = {3, 7, 12, 21}
chess = {7, 9, 12}
print(cricket & chess)
print(cricket | chess)
print(cricket - chess)

cricket.add(5)
cricket.discard(21)
print(sorted(cricket))

visitors = ["Kochi", "Mysuru", "Kochi", "Hampi"]
print(sorted(set(visitors)))
Output
{3, 12, 21, 7}
4
{12, 7}
{3, 21, 7, 9, 12}
{3, 21}
[3, 5, 7, 12]
['Hampi', 'Kochi', 'Mysuru']

Look closely at the first line of output: {3, 12, 21, 7}. The duplicates are gone, but the numbers are in neither the original order nor sorted order. A set arranges its items in whatever way makes lookups fastest. That is the trade-off: you give up order, and in return checking 7 in cricket stays fast even with a million items. add() puts in one value, and discard() removes one without complaining if it is missing (remove() would raise a KeyError).

Watch out: Sets have no order and no index, so unique[0] is an error. When a set holds strings, the order in which it prints can even change from one run of the program to the next. If order matters, convert the set to a sorted list with sorted(my_set), as in the last line.

Tip: Choose the collection by the question you ask most: “what is item number 3?” → list; “what is the value for this name?” → dictionary; “have I seen this before?” → set; “fixed group of values” → tuple.

Further reading

Key takeaways

  • A dictionary maps unique keys to values: {"idli": 40}; read with d[key] or safely with d.get(key, default).
  • Assigning to a key adds or updates it; del and pop() remove it.
  • Loop with for key, value in d.items(); dictionaries keep insertion order.
  • Count things with d[k] = d.get(k, 0) + 1.
  • Sets hold unique, unordered values and support |, & and -; use set() for an empty set.

Quick quiz

Check what you learned – pick an answer.

1. prices = {"tea": 15}. What does prices.get("coffee", 0) return?

2. What is len({4, 4, 2, 2, 9})?

3. Which line creates an empty set?

Practice exercise

Given orders = [("Arjun", 450), ("Zoya", 1200), ("Arjun", 300), ("Kiran", 800), ("Zoya", 150)], build a dictionary with each customer's total spending, then print each customer and total, highest spender first.

Show a hint

Use totals[name] = totals.get(name, 0) + amount. To sort by value, use sorted(totals.items(), key=lambda pair: pair[1], reverse=True).

Show the solution
orders = [("Arjun", 450), ("Zoya", 1200), ("Arjun", 300), ("Kiran", 800), ("Zoya", 150)]
totals = {}

for name, amount in orders:
    totals[name] = totals.get(name, 0) + amount

for name, total in sorted(totals.items(), key=lambda pair: pair[1], reverse=True):
    print(f"{name}: ₹{total}")

Progress is saved in this browser only.