Dictionaries in Python

Reviewed & published by Brayan K

Store and access data using key-value pairs for fast and organized data management.

Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1. What Are Dictionaries?

A dictionary stores data in key-value pairs. Instead of accessing items by position (like lists), you access them by a unique key name.

Key Characteristics

2. Lists vs Dictionaries

Understanding when to use each:

FeatureListDictionary
Access byIndex (0, 1, 2...)Key name
Syntax[item1, item2]
Best forOrdered collectionsNamed/labeled data
Example useList of namesUser profile info
fruits = ["apple", "banana"]
print(fruits[0])  # apple
person = {"name": "Alice"}
print(person["name"])  # Alice

3. Creating Dictionaries

MethodExampleDescription
Empty dictionarymy_dict = {}Start with nothing
With dataKey-value pairs
Using dict()dict(name="Alice")Constructor function
# Different ways to create dictionaries

# Empty dictionary
my_dict = {}
print("Empty:", my_dict)

# Dictionary with data
person = {
    "name": "Alice",
    "age": 25,
    "city": "London"
}
print("Person:", person)

# Using dict() constructor
info = dict(name="Bob", age=30, job="Developer")
print("Info:", info)

# Mixed value types
product = {
    "id": 101,
    "name": "Laptop",
    "price": 999.99,
    "in_stock": True
}
print("Product:", product)

# ✅ Expected output:
# Empty: {}
# Person: {'name': 'Alice', 'age': 25, 'city': 'London'}
# Info: {'name': 'Bob', 'age': 30, 'job': 'Developer'}
# Product: {'id': 101, 'name': 'Laptop', 'price': 999.99, 'in_stock': True}

4. Accessing Values

There are two ways to access dictionary values:

MethodSyntaxIf Key Missing
Square bracketsdict["key"]KeyError (crashes)
.get() methoddict.get("key")Returns None (safe)
.get() with defaultdict.get("key", "default")Returns your default
person = {"name": "Alice", "age": 25}

# Method 1: Square brackets (fast but risky)
print("Name:", person["name"])

# Method 2: .get() method (safe)
print("Age:", person.get("age"))

# .get() with missing key
print("Email:", person.get("email"))          # Returns None
print("Email:", person.get("email", "N/A"))   # Returns "N/A"

# Square brackets with missing key would crash:
# print(person["email"])  # KeyError!

# ✅ Expected output:
# Name: Alice
# Age: 25
# Email: None
# Email: N/A

5. Adding and Changing Items

Dictionaries are mutable — you can add new key-value pairs or update existing ones using the same syntax:

person = {"name": "Alice"}
print("Start:", person)

# Add new key-value pair
person["age"] = 25
print("After adding age:", person)

# Add another
person["city"] = "London"
print("After adding city:", person)

# Change existing value
person["age"] = 26
print("After changing age:", person)

# Add multiple with .update()
person.update({"job": "Developer", "country": "UK"})
print("After update:", person)

# ✅ Expected output:
# Start: {'name': 'Alice'}
# After adding age: {'name': 'Alice', 'age': 25}
# After adding city: {'name': 'Alice', 'age': 25, 'city': 'London'}
# After changing age: {'name': 'Alice', 'age': 26, 'city': 'London'}
# After update: {'name': 'Alice', 'age': 26, 'city': 'London', 'job': 'Developer', 'country': 'UK'}

6. Removing Items

MethodWhat It DoesExample
del dict["key"]Delete a specific keydel person["age"]
.pop("key")Remove and return the valueage = person.pop("age")
.popitem()Remove last inserted itemlast = person.popitem()
.clear()Remove all itemsperson.clear()
person = {"name": "Alice", "age": 25, "city": "London"}
print("Start:", person)

# del - delete by key
del person["city"]
print("After del:", person)

# pop - remove and get the value
age = person.pop("age")
print(f"Popped age: {age}")
print("After pop:", person)

# pop with default (safe)
job = person.pop("job", "Not found")
print(f"Popped job: {job}")

# ✅ Expected output:
# Start: {'name': 'Alice', 'age': 25, 'city': 'London'}
# After del: {'name': 'Alice', 'age': 25}
# Popped age: 25
# After pop: {'name': 'Alice'}
# Popped job: Not found

7. Checking if a Key Exists

Use in to check if a key exists before accessing it:

person = {"name": "Alice", "age": 25}

# Check if key exists
if "name" in person:
    print("Name found:", person["name"])

if "email" in person:
    print("Email:", person["email"])
else:
    print("Email not found")

# Check if key does NOT exist
if "phone" not in person:
    print("Phone number not stored")

# Practical pattern: safe access
key = "city"
if key in person:
    print(f"{key}: {person[key]}")
else:
    print(f"{key} is not in the dictionary")

# ✅ Expected output:
# Name found: Alice
# Email not found
# Phone number not stored
# city is not in the dictionary

8. Looping Through Dictionaries

Loop TypeWhat You GetSyntax
Keys onlyEach keyfor key in dict:
Values onlyEach valuefor val in dict.values():
BothKey and valuefor key, val in dict.items():
person = {"name": "Alice", "age": 25, "city": "London"}

# Loop through keys (default)
print("Keys:")
for key in person:
    print(f"  {key}")

# Loop through values
print("\nValues:")
for value in person.values():
    print(f"  {value}")

# Loop through key-value pairs (most common)
print("\nKey-Value pairs:")
for key, value in person.items():
    print(f"  {key}: {value}")

# ✅ Expected output:
# Keys:
#   name
#   age
#   city
#
# Values:
#   Alice
#   25
#   London
#
# Key-Value pairs:
#   name: Alice
#   age: 25
#   city: London

🟢 Worked Example: a tiny stock room

Everything from the sections above now lands on one piece of data. Read the comments first, then run it and check each printed line against the code that made it. This is the shape of almost every real dictionary job: create it, look things up safely, change it, then loop over it.

# 🟢 WORKED EXAMPLE — a tiny stock room, start to finish

stock = {                 # keys are item names (strings), values are quantities (numbers)
    "apples": 12,
    "bananas": 5,
    "cherries": 0,
}

# 1. Look something up. Square brackets need the key to actually exist...
print("Apples in stock:", stock["apples"])

# ...whereas .get() returns a fallback instead of crashing with KeyError.
print("Kiwis in stock:", stock.get("kiwis", 0))     # no "kiwis" key, so you get the 0

# 2. Add a new item just by assigning to a key that is not there yet.
stock["kiwis"] = 7
print("After adding kiwis:", stock)

# 3. Change an existing one exactly the same way. += works because the value is a number.
stock["bananas"] += 3                               # 5 + 3
print("Bananas now:", stock["bananas"])

# 4. Remove one. pop() deletes the key AND hands you back the value it removed.
sold_out = stock.pop("cherries")
print("Removed cherries, which had:", sold_out)

# 5. Loop over keys and values together with .items().
print("Full stock list:")
for item, qty in stock.items():
    print(f"  {item}: {qty}")

# 6. A dictionary can answer questions about itself.
print("Number of different items:", len(stock))     # counts keys
print("Total units on the shelf:", sum(stock.values()))
print("Do we sell apples?", "apples" in stock)      # 'in' searches KEYS...
print("Do we sell 12?", 12 in stock)                # ...never values, so this is False

# ✅ Expected output:
# Apples in stock: 12
# Kiwis in stock: 0
# After adding kiwis: {'apples': 12, 'bananas': 5, 'cherries': 0, 'kiwis': 7}
# Bananas now: 8
# Removed cherries, which had: 0
# Full stock list:
#   apples: 12
#   bananas: 8
#   kiwis: 7
# Number of different items: 3
# Total units on the shelf: 27
# Do we sell apples? True
# Do we sell 12? False

🎯 Your Turn: the café price list

Your go. Everything is written except three small pieces — the parts that are actually about dictionaries. Fill in each ___, run it, and compare with the expected output at the bottom of the file.

# 🎯 YOUR TURN — fill in the blanks marked with ___

prices = {"tea": 120, "coffee": 275, "cake": 340}    # prices in pence

# 1) Print the price of coffee. Square brackets take the KEY, not a number.
print("Coffee costs:", prices[___], "pence")         # 👉 replace ___ with "coffee" (quotes included)

# 2) Juice is not on the list. Ask for it WITHOUT crashing, falling back to 0.
print("Juice costs :", prices.___("juice", 0), "pence")   # 👉 which method takes a fallback?

# 3) Add juice to the menu at 199p by assigning to a brand-new key.
prices[___] = 199                                    # 👉 replace ___ with "juice"

# Already written for you: print the whole menu, one item per line.
for item, pence in prices.items():
    print(f"  {item}: {pence}p")

print("Items on the menu:", len(prices))

# ✅ Expected output:
# Coffee costs: 275 pence
# Juice costs : 0 pence
#   tea: 120p
#   coffee: 275p
#   cake: 340p
#   juice: 199p
# Items on the menu: 4

Line 2 catches nearly everyone: juice is printed as 0 before you add it on the next line, because Python runs the file top to bottom. That is not a bug — it is the order of events.

9. Useful Dictionary Methods

MethodWhat It ReturnsExample
.keys()All keysperson.keys()
.values()All valuesperson.values()
.items()All key-value pairsperson.items()
.get(key)Value or Noneperson.get("name")
.update(dict2)Merges dict2 into dict
.copy()A copy of the dictnew = person.copy()
len(dict)Number of pairslen(person)
person = {"name": "Alice", "age": 25, "city": "London"}

# Get all keys
print("Keys:", list(person.keys()))

# Get all values
print("Values:", list(person.values()))

# Get all items as tuples
print("Items:", list(person.items()))

# Count pairs
print(f"Number of items: {len(person)}")

# Make a copy
person_copy = person.copy()
person_copy["name"] = "Bob"
print(f"Original name: {person['name']}")
print(f"Copy name: {person_copy['name']}")

# ✅ Expected output:
# Keys: ['name', 'age', 'city']
# Values: ['Alice', 25, 'London']
# Items: [('name', 'Alice'), ('age', 25), ('city', 'London')]
# Number of items: 3
# Original name: Alice
# Copy name: Bob

10. Nested Dictionaries

Dictionaries can contain other dictionaries (or lists) as values. This is useful for organizing complex data.

# Nested dictionary - users with details
users = {
    "user1": {
        "name": "Alice",
        "age": 25,
        "email": "[email protected]"
    },
    "user2": {
        "name": "Bob",
        "age": 30,
        "email": "[email protected]"
    }
}

# Access nested values
print("User1 name:", users["user1"]["name"])
print("User2 email:", users["user2"]["email"])

# Loop through nested dict
print("\nAll users:")
for user_id, info in users.items():
    print(f"  {user_id}: {info['name']} ({info['age']})")

# ✅ Expected output:
# User1 name: Alice
# User2 email: [email protected]
#
# All users:
#   user1: Alice (25)
#   user2: Bob (30)

11. Dictionary Comprehension (Advanced)

Like list comprehension, you can create dictionaries in one line:

# Create a dictionary of squares
squares = {x: x**2 for x in range(1, 6)}
print("Squares:", squares)

# Create from two lists
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
people = {name: age for name, age in zip(names, ages)}
print("People:", people)

# With condition
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print("Even squares:", even_squares)

# ✅ Expected output:
# Squares: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# People: {'Alice': 25, 'Bob': 30, 'Charlie': 35}
# Even squares: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

12. Common Mistakes to Avoid

MistakeProblemSolution
Accessing missing keydict["missing"]Use .get() or check with in
Using list as keyKeys must be immutable (str, int, tuple)
Using square brackets["key", "value"]Use curly braces
Forgetting the colonUse
Duplicate keysEach key must be unique (last value wins)

13. Practical Examples

Example 1: User Profile

# Store user information
user = {
    "username": "alice123",
    "email": "[email protected]",
    "age": 25,
    "is_verified": True
}

# Display profile
print("=== User Profile ===")
for key, value in user.items():
    print(f"{key}: {value}")

# Update email
user["email"] = "[email protected]"
print(f"\nUpdated email: {user['email']}")

# ✅ Expected output:
# === User Profile ===
# username: alice123
# email: [email protected]
# age: 25
# is_verified: True
#
# Updated email: [email protected]

Example 2: Word Counter

# Count word occurrences
text = "apple banana apple cherry banana apple"
words = text.split()

word_count = {}
for word in words:
    if word in word_count:
        word_count[word] += 1
    else:
        word_count[word] = 1

print("Word counts:")
for word, count in word_count.items():
    print(f"  {word}: {count}")

# ✅ Expected output:
# Word counts:
#   apple: 3
#   banana: 2
#   cherry: 1

Example 3: Simple Contact Book

# Contact book
contacts = {
    "Alice": "123-456-7890",
    "Bob": "234-567-8901",
    "Charlie": "345-678-9012"
}

# Look up a contact
name = "Bob"
if name in contacts:
    print(f"{name}'s number: {contacts[name]}")
else:
    print(f"{name} not found")

# Add new contact
contacts["Diana"] = "456-789-0123"

# List all contacts
print("\nAll contacts:")
for name, phone in contacts.items():
    print(f"  {name}: {phone}")

# ✅ Expected output:
# Bob's number: 234-567-8901
#
# All contacts:
#   Alice: 123-456-7890
#   Bob: 234-567-8901
#   Charlie: 345-678-9012
#   Diana: 456-789-0123

🏁 Mini-Challenge: count the votes

No blanks this time — just the brief and an empty outline. You have a list of votes with repeats in it. Turn it into a dictionary of vote counts, print each candidate on its own line in the order they first appear, then announce the winner.

The whole trick is one line inside the loop: counts[vote] = counts.get(vote, 0) + 1 reads "whatever this name is on so far (0 if it is new), plus one". Try to get there yourself before you read that again.

# 🏁 MINI-CHALLENGE — write it yourself

votes = ["ana", "ben", "ana", "cara", "ana", "ben"]

# 1. Start with an empty dictionary called counts.
# 2. Loop over votes. For each name, add 1 to its entry in counts.
#    Careful: the first time you see a name it has no entry yet,
#    so .get(name, 0) is safer than counts[name].
# 3. Loop over counts.items() and print "name: number", one per line.
# 4. Find the winner. max(counts, key=counts.get) gives the key with
#    the biggest value — then print the name and its count.

# your code here


# ✅ Expected output:
# ana: 3
# ben: 2
# cara: 1
# Winner: ana with 3 votes

Summary: Quick Reference

OperationSyntaxExample
Create
Access (unsafe)dict["key"]person["name"]
Access (safe)dict.get("key")person.get("name")
Add/Changedict["key"] = valperson["age"] = 25
Removedel dict["key"]del person["age"]
Check exists"key" in dict"name" in person
Loopfor k, v in dict.items():for k, v in person.items():
Lengthlen(dict)len(person)

Lesson done — you can now model real-world data in Python!

Dictionaries are how Python stores structured data — user profiles, API responses, config settings. You know how to create, access, update, loop, and nest them safely.

Practice quiz

How does a dictionary store data?

  • By index position
  • In key-value pairs
  • As a sorted set
  • As a fixed tuple

Answer: In key-value pairs. Dictionaries store data as key-value pairs, accessed by key name.

Which brackets create a dictionary?

  • [ ]
  • ( )
  • { }
  • < >

Answer: { }. Dictionaries use curly braces, e.g. {"name": "Alice"}.

What happens when you access a missing key with dict['missing']?

  • Returns None
  • Returns 0
  • Raises a KeyError
  • Adds the key

Answer: Raises a KeyError. Square-bracket access on a missing key raises a KeyError.

What does person.get('email', 'N/A') return if 'email' is missing?

  • None
  • 'N/A'
  • KeyError
  • Empty string

Answer: 'N/A'. .get() returns the supplied default ('N/A') when the key is absent.

How do you add a new key 'age' with value 25 to dict person?

  • person.add('age', 25)
  • person['age'] = 25
  • person.append(25)
  • person.insert('age', 25)

Answer: person['age'] = 25. Assigning to a new key, person['age'] = 25, adds the pair.

Which loop gives you both keys and values?

  • for k in dict:
  • for v in dict.values():
  • for k, v in dict.items():
  • for i in dict.keys():

Answer: for k, v in dict.items():. .items() yields (key, value) pairs you can unpack in the loop.

Can a list be used as a dictionary key?

  • Yes, always
  • No, keys must be immutable
  • Only if it's empty
  • Only with .get()

Answer: No, keys must be immutable. Keys must be immutable (str, int, tuple); a list raises a TypeError.

What does {x: x**2 for x in range(1, 6)} create?

  • {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
  • {1, 4, 9, 16, 25}
  • [1, 4, 9, 16, 25]
  • {0: 0, 1: 1, ...}

Answer: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}. The dict comprehension maps each x (1-5) to its square.

If a dictionary literal has a duplicate key {'a': 1, 'a': 2}, what is the value of 'a'?

  • 1
  • 2
  • Error
  • [1, 2]

Answer: 2. Keys are unique; the last value wins, so 'a' is 2.

What does len() return for {'name': 'Alice', 'age': 25, 'city': 'London'}?

  • 2
  • 3
  • 6
  • 1

Answer: 3. len() counts the number of key-value pairs: 3.

Continue this course