A dictionary is Python’s built-in key-value data structure. Think of it like a real dictionary — we look up a word (key) to find its definition (value). Under the hood, it’s a hash map, so lookups are O(1) on average.
Creating Dictionaries
# Literal syntax — most common
user = {"name": "Manish", "age": 25, "active": True}
# Using dict() constructor
user = dict(name="Manish", age=25, active=True)
# From a list of tuples
user = dict([("name", "Manish"), ("age", 25)])
# fromkeys — same value for all keys
defaults = dict.fromkeys(["a", "b", "c"], 0) # {'a': 0, 'b': 0, 'c': 0}
Accessing Values
user = {"name": "Manish", "age": 25}
user["name"] # "Manish" — raises KeyError if key doesn't exist
user.get("name") # "Manish" — returns None if key doesn't exist
user.get("email", "N/A") # "N/A" — custom default value
The get() method is almost always preferred because it won’t crash our program if a key is missing.
Essential Methods
user = {"name": "Manish", "age": 25}
user.keys() # dict_keys(['name', 'age'])
user.values() # dict_values(['Manish', 25])
user.items() # dict_items([('name', 'Manish'), ('age', 25)])
# setdefault — get value if key exists, otherwise set it and return the default
user.setdefault("email", "none@example.com")
# user is now {'name': 'Manish', 'age': 25, 'email': 'none@example.com'}
# update — merge another dict into this one
user.update({"age": 26, "city": "Delhi"})
# pop — remove key and return its value
age = user.pop("age") # 26
missing = user.pop("x", -1) # -1 (default if key not found)
# del — remove a key (raises KeyError if missing)
del user["city"]
Iterating Over Dicts
scores = {"math": 90, "science": 85, "english": 92}
# Iterate over keys (default)
for subject in scores:
print(subject)
# Iterate over key-value pairs — most useful
for subject, score in scores.items():
print(f"{subject}: {score}")
Dict Comprehensions
Just like list comprehensions, but for dictionaries.
# Square numbers as values
squares = {n: n**2 for n in range(1, 6)}
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Flip keys and values
original = {"a": 1, "b": 2}
flipped = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b'}
Merging Dicts (Python 3.9+)
The | operator makes merging clean and readable.
defaults = {"theme": "dark", "lang": "en"}
overrides = {"lang": "hi", "font": "mono"}
merged = defaults | overrides
# {'theme': 'dark', 'lang': 'hi', 'font': 'mono'}
# In-place merge
defaults |= overrides
defaultdict
From the collections module — it auto-creates missing keys with a default factory.
from collections import defaultdict
# Count word frequency
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
counter = defaultdict(int) # missing keys default to 0
for word in words:
counter[word] += 1
# defaultdict(<class 'int'>, {'apple': 3, 'banana': 2, 'cherry': 1})
In simple language, dictionaries are our go-to when we need to associate one piece of data with another. Fast, flexible, and used everywhere in Python.