A dictionary (dict) stores key-value pairs, providing fast O(1) average-case lookup by key — Python's built-in hash map.
ages = {"Rahim": 25, "Karim": 30}
ages["Nadia"] = 22 # add a new key
print(ages["Rahim"]) # 25 — KeyError if "Rahim" doesn't exist
print(ages.get("Unknown", 0)) # 0 — .get() with a default avoids KeyError
if "Karim" in ages: # membership test checks KEYS
print("Karim is in the dict")
for name, age in ages.items(): # iterate over key-value pairs
print(name, age)
ages.setdefault("Rahim", 0) # only sets if key is missing — no-op here
del ages["Nadia"] # remove a key
dict[key] raises a KeyError if the key doesn't exist — use .get(key, default) when a missing key should quietly produce a fallback value instead of crashing, and .setdefault(key, default) when you want to insert a default only if the key isn't already present.
Since Python 3.7, dictionaries officially preserve insertion order — iterating with .items(), .keys(), or .values() always visits entries in the order they were added, a guarantee that wasn't part of the language before (an implementation detail became an official language feature).
Dict keys must be hashable (immutable types like strings, numbers, and tuples qualify; lists and other dicts don't), which is exactly why tuples are commonly used as composite dict keys (e.g., grid[(x, y)] = value for a 2D grid).