0%

10- Dictionaries in Python

A dictionary stores data in key-value pairs. Like a phonebook: you look up a name (key) to find a number (value). Fast, flexible, and everywhere in Python.

A list stores items in order. You ask for item number 0, item number 1, and so on. But sometimes you do not want to remember numbers. You want to remember names. You have a student’s name. You want their grade. You have a product name. You want its price. You have a username. You want their email address. This is what dictionaries are for. They store pairs of information: a key and a value. You use the key to look up the value. No numbers needed. Just meaningful names.

🕯️ Magic Note

Dictionaries are also called “hash maps” or “associative arrays” in other languages. Python dictionaries are incredibly fast at looking up values by key. No matter how many items are in the dictionary, finding a key takes almost the same time. This is why they are used everywhere.

Creating Dictionaries
Use curly braces { } to create a dictionary. Separate keys and values with a colon :. Separate pairs with commas.

Python

# Empty dictionary

empty = {}

# Dictionary with string keys and integer values

ages = {“Ali”: 25, “Sara”: 30, “Reza”: 28}

# Dictionary with mixed key types

mixed = {“name”: “Feloriya”, 42: “answer”, 3.14: “pi”}

# Dictionary can hold any type of values

person = {

“name”: “Feloriya”,

“age”: 25,

“skills”: [“Python”, “Web Design”, “SEO”],

“is_active”: True

}

# Using the dict() constructor

fruits = dict(apple=5, banana=3, cherry=8)

# {‘apple’: 5, ‘banana’: 3, ‘cherry’: 8}

💡 Use dict() when your keys are valid variable names (no spaces, no special characters). Use curly braces { } for all other cases. Most Python programmers use curly braces.
Accessing Values by Key
Use square brackets with the key to get its value. If the key does not exist, Python raises a KeyError.

Python

ages = {“Ali”: 25, “Sara”: 30, “Reza”: 28}

print(ages[“Ali”]) # 25

print(ages[“Sara”]) # 30

# This causes KeyError

# print(ages[“Mehdi”]) # KeyError: ‘Mehdi’

⚠️ Using square brackets with a missing key raises a KeyError and stops your program. Use .get() (explained below) for safe access with a default value.
Safe Access with .get()
The .get() method returns the value if the key exists. Otherwise, it returns None (or a default value you provide). No error. No crash.

Python

ages = {“Ali”: 25, “Sara”: 30, “Reza”: 28}

print(ages.get(“Ali”)) # 25

print(ages.get(“Mehdi”)) # None (no error)

print(ages.get(“Mehdi”, 0)) # 0 (custom default)

print(ages.get(“Sara”, 0)) # 30 (ignores default because key exists)

💡 Use .get() whenever you are not 100% sure a key exists. It saves you from unexpected crashes and makes your code more robust.
Adding and Modifying Items
Dictionaries are mutable. You can add new key-value pairs or change existing ones using the same square bracket syntax.

Python

ages = {“Ali”: 25, “Sara”: 30}

print(ages) # {‘Ali’: 25, ‘Sara’: 30}

# Change an existing key

ages[“Ali”] = 26

print(ages) # {‘Ali’: 26, ‘Sara’: 30}

# Add a new key-value pair

ages[“Reza”] = 28

print(ages) # {‘Ali’: 26, ‘Sara’: 30, ‘Reza’: 28}

🕯️ Magic Note

There is no “add” method. The same syntax dictionary[key] = value both adds (if key is new) and updates (if key exists). This is simple and intentional.

Removing Items
Use .pop() to remove a key and return its value. Use del to remove a key without needing the value. Use .clear() to remove everything.

Python

person = {“name”: “Feloriya”, “age”: 25, “city”: “Tehran”}

# .pop() removes and returns the value

age = person.pop(“age”)

print(age) # 25

print(person) # {‘name’: ‘Feloriya’, ‘city’: ‘Tehran’}

# del removes without returning

del person[“city”]

print(person) # {‘name’: ‘Feloriya’}

# .popitem() removes and returns the last inserted pair (Python 3.7+)

person[“age”] = 25

person[“city”] = “Tehran”

last = person.popitem()

print(last) # (‘city’, ‘Tehran’)

# .clear() removes everything

person.clear()

print(person) # {}

⚠️ .pop() raises a KeyError if the key does not exist. Use .pop(key, default) to provide a fallback value.
Checking if a Key Exists
Use the in operator to check if a key exists in a dictionary. This is fast and readable.

Python

ages = {“Ali”: 25, “Sara”: 30, “Reza”: 28}

print(“Ali” in ages) # True

print(“Mehdi” in ages) # False

print(“Ali” not in ages) # False

print(“Mehdi” not in ages) # True

# Safely remove a key if it exists

if “Ali” in ages:

del ages[“Ali”]

💡 Checking with in is fast even for huge dictionaries. Always check before accessing if you are unsure.
Getting All Keys, Values, and Items
Dictionaries provide views of their data: .keys(), .values(), and .items(). These are dynamic views that update when the dictionary changes.

Python

person = {“name”: “Feloriya”, “age”: 25, “skill”: “Python”}

# All keys

print(person.keys()) # dict_keys([‘name’, ‘age’, ‘skill’])

# All values

print(person.values()) # dict_values([‘Feloriya’, 25, ‘Python’])

# All key-value pairs as tuples

print(person.items()) # dict_items([(‘name’, ‘Feloriya’), (‘age’, 25), (‘skill’, ‘Python’)])

# Convert to a list if needed

keys_list = list(person.keys())

print(keys_list) # [‘name’, ‘age’, ‘skill’]

🕯️ Magic Note

In Python 3.7 and later, dictionaries preserve insertion order. This means .keys(), .values(), and .items() return items in the order you added them. Before Python 3.7, dictionaries were unordered.

Looping Through Dictionaries
Use for loops with dictionaries. The default loop iterates over keys. Use .values() for values, and .items() for both key and value simultaneously.

Python

ages = {“Ali”: 25, “Sara”: 30, “Reza”: 28}

# Looping through keys (default)

for name in ages:

print(name)

# Output: Ali, Sara, Reza

# Looping through values

for age in ages.values():

print(age)

# Output: 25, 30, 28

# Looping through both key and value (most common)

for name, age in ages.items():

print(f”{name} is {age} years old”)

# Ali is 25 years old

# Sara is 30 years old

# Reza is 28 years old

💡 The pattern for key, value in dictionary.items(): is one of the most common and useful Python idioms. Master it.
Dictionary Length
The len() function returns the number of key-value pairs.

Python

person = {“name”: “Feloriya”, “age”: 25, “skill”: “Python”}

print(len(person)) # 3

empty = {}

print(len(empty)) # 0

print(not empty) # True (empty dict is falsy)

Merging Dictionaries
In Python 3.9 and later, you can merge dictionaries using the | operator. Use .update() for older versions.

Python

dict1 = {“a”: 1, “b”: 2}

dict2 = {“c”: 3, “d”: 4}

# Python 3.9+ (creates a new dictionary)

merged = dict1 | dict2

print(merged) # {‘a’: 1, ‘b’: 2, ‘c’: 3, ‘d’: 4}

# .update() modifies the original

dict1.update(dict2)

print(dict1) # {‘a’: 1, ‘b’: 2, ‘c’: 3, ‘d’: 4}

# For Python 3.5+ (creating a new dictionary)

merged = {**dict1, **dict2}

⚠️ When merging, if the same key appears in both dictionaries, the value from the second dictionary overwrites the first. This is usually what you want.
Nested Dictionaries
Dictionaries can contain other dictionaries. This allows you to model complex, hierarchical data.

Python

users = {

“ali”: {

“age”: 25,

“email”: “ali@example.com”,

“score”: 95

},

“sara”: {

“age”: 30,

“email”: “sara@example.com”,

“score”: 88

}

}

print(users[“ali”][“email”]) # ali@example.com

print(users[“sara”][“score”]) # 88

# Loop through nested dictionary

for username, info in users.items():

print(f”User: {username}, Age: {info[‘age’]}”)

Dictionary Comprehensions
Just like list comprehensions, you can create dictionaries using a concise syntax. This is an advanced but powerful feature.

Python

# Create a dictionary of squares: {1:1, 2:4, 3:9, 4:16, 5:25}

squares = {x: x**2 for x in range(1, 6)}

print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Filtered comprehension

even_squares = {x: x**2 for x in range(1, 11) if x % 2 == 0}

print(even_squares) # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}

# Swapping keys and values

original = {“a”: 1, “b”: 2, “c”: 3}

swapped = {v: k for k, v in original.items()}

print(swapped) # {1: ‘a’, 2: ‘b’, 3: ‘c’}

Valid Keys and Values
Dictionary keys must be immutable (unchangeable). Strings, numbers, and tuples are valid. Lists and other dictionaries are not valid keys because they can change. Values can be anything: numbers, strings, lists, dictionaries, functions, even objects.

Python

# Valid keys (immutable types)

valid = {

“string”: 1,

42: 2,

3.14: 3,

(1, 2): 4, # tuple is immutable

True: 5

}

# Invalid keys (mutable types) – will cause TypeError

# invalid = {[1, 2]: “list”} # TypeError: unhashable type: ‘list’

# invalid = {{“a”: 1}: “dict”} # TypeError: unhashable type: ‘dict’

⚠️ If you try to use a list as a dictionary key, Python will raise a TypeError: unhashable type: ‘list’. Lists are not allowed because they can change. Use a tuple instead if you need a sequence as a key.
Common Mistakes with Dictionaries
  • Forgetting that dictionary keys must be immutable (strings, numbers, tuples)
  • Using square brackets with a missing key instead of .get()
  • Assuming dictionaries preserve order in old Python versions (pre-3.7)
  • Modifying a dictionary while iterating over it (causes errors)
  • Confusing in for keys vs values: value in dict checks keys, not values
  • Using .pop() without a default and the key is missing
Check Your Understanding
  • How do you create a dictionary mapping “apple” to 5 and “banana” to 3?
  • What is the difference between dict[“key”] and dict.get(“key”)?
  • How do you check if a key exists in a dictionary?
  • Write a loop that prints both the name and age from ages = {“Ali”: 25, “Sara”: 30}
  • What happens if you try to use a list as a dictionary key?
  • How do you merge two dictionaries into a new one?

⚡ Whisper

A dictionary is a book of whispers. Each whisper has a caller (the key) and a secret (the value). You do not need to remember the page number. You only need to remember the caller’s name. Speak the key, and Python finds the whisper instantly, even among thousands. This is the conjure of mapping. This is how you organize chaos into meaning. Build your dictionaries carefully. Choose keys that make sense. Let each value hold exactly what it promises. And when you need a whisper back, you will find it waiting exactly where you left it.

Related posts