Dictionaries: Beginner

Reddit stores each post's metadata - vote count, comment count, author, subreddit, awards, and flair - in a dictionary that travels from the database through the API to the browser, making Python's dict the universal data format gluing together every layer of a modern web application. Every JSON response from an API, every database record mapped into Python, and every configuration file loaded at startup becomes a dictionary the moment it enters your program. The dictionary skills you are about to learn are the most-used data structure in all of Python.

What is a Dictionary?

Daily Life
Interviews

Look up data by name, not position

1user_data = ["Alice", "alice@email.com", 28, True]
2print(user_data[0])
3print(user_data[2])
>>>Output
Alice
28
LISTDICT
LIST
Position-based
user_data[2] means what?
DICT
Name-based
user["age"] is crystal clear
A dictionary in Python is a collection that stores data as key-value pairs. Instead of accessing items by their position (like in a list), you access them by their key. The key is a unique identifier, and the value is whatever data you want to associate with that key.

The Real Dictionary Analogy

The name "dictionary" comes from actual word dictionaries. In a physical dictionary, you look up a word (the key) to find its definition (the value). You don't say "give me the 4,532nd word." You say "give me the definition of 'ephemeral'." The word IS the lookup mechanism.
List: position-based
List: position-based
Give me item at position 3. What does index 3 mean? You have to memorize it.
Dictionary: name-based
Dictionary: name-based
Give me the value for "email". The key itself tells you what the data means.
This key-based lookup concept is so fundamental that every major language has its own version.
Try it yourself. Fill in the blanks to access values from this dictionary using their keys.
Python Quiz

> Access the "name" and "email" values from this dictionary. Remember: dictionaries use string keys, not numeric indices like lists.

user = {
    "name": "Alice",
    "email": "a@b.com"
}
print(user[___])
print(user[___])
name
email
"name"
"email"
0
1

Key-based access is what makes dictionaries so readable in practice. When you see user["name"] in production code six months after writing it, the meaning is obvious. With position-based access, you would need to look up which index is which.

Dictionaries are unordered collections in the sense that you cannot access items by position. However, since Python 3.7, dictionaries do preserve insertion order, so looping over them will always give you items in the order they were added.
Every major programming language has a dictionary-like type because mapping names to values is fundamental to organizing data. Mastering Python's dict puts you on solid ground for every data engineering task you will encounter.

Creating Dictionaries

Daily Life
Interviews

Build key-value data structures

Python uses curly braces {} to create dictionaries. Inside the braces, you write key-value pairs separated by colons. Multiple pairs are separated by commas. Let's revisit that user profile problem with a dictionary:
1user = {
2 "name": "Alice",
3 "email": "alice@email.com",
4 "age": 28,
5 "is_premium": True
6}
7print(user)
>>>Output
{'name': 'Alice', 'email': 'alice@email.com', 'age': 28, 'is_premium': True}
Now your data is self-documenting. Anyone reading this code immediately understands what each piece of data represents. The key "name" tells you it's a name. The key "age" tells you it's an age. No memorization required.

Syntax Breakdown

Understanding the syntax elements helps you read and write dictionaries confidently. Each piece has a specific purpose.
01
{ } Curly Braces
Wrap the entire dictionary, marking its start and end
02
: Colon
Separates each key from its value inside the pair
03
, Comma
Separates different key-value pairs from each other
04
"key" Strings
Keys are typically strings in quotes; values can be any type

Empty Dictionary

Sometimes you need to create an empty dictionary and add items to it later. There are two ways to create an empty dictionary:
1empty_dict = {}
2
3also_empty = dict()
4
5print(type(empty_dict))
6print(len(empty_dict))
>>>Output
<class 'dict'>
0
TIP
Most Python developers prefer {} over dict() for creating empty dictionaries. It's shorter, faster, and more idiomatic. You'll see {} used in virtually all professional codebases.
Fill in the blanks to create an empty dictionary and check the type of an existing one.
Python Quiz

> Create an empty dictionary and use the correct function to check the type of config. Remember: dictionaries use curly braces, not brackets or parentheses.

config = {
    "host": "localhost",
    "port": 5432
}
empty = {}
print(___(config))
print(len(empty))
{}
[]
()
type
len
dict
The curly-brace syntax for dictionaries is shared with sets, but the colon separator makes them distinct. Curly braces with key: value pairs create a dict; curly braces with bare values create a set.
Values in a dictionary can be any Python type: strings, numbers, booleans, lists, other dictionaries, or even functions. This flexibility lets you represent complex, real-world data structures naturally.
Starting with an empty dictionary and building it up with assignments is a common pattern for constructing results. You initialize the container, then populate it as you process each record in a loop.

Accessing Values

Daily Life
Interviews

Retrieve values safely from any dict

To retrieve a value from a dictionary, you use square brackets with the key inside. This looks similar to list indexing, but instead of a number, you provide the key name:
1user = {"name": "Alice", "age": 28, "city": "Seattle"}
2
3# Access values using their keys
4print(user["name"])
5print(user["age"])
6print(user["city"])
>>>Output
Alice
28
Seattle
This is the fundamental operation that makes dictionaries powerful. You're saying "give me the value associated with this key" rather than "give me the value at this position."

Handling Missing Keys

If you try to access a key that doesn't exist, Python raises a KeyError. This is different from lists, where accessing an invalid index raises an IndexError. Let's see what happens:
1user = {"name": "Alice", "age": 28}
2
3# This key exists, works fine
4print(user["name"])
5
6# This key does NOT exist
7# print(user["email"])
>>>Output
Alice
Do
  • Use dict[key] when you know the key exists
  • Use .get(key) when the key might be missing
  • Check with "key in dict" before accessing
Don't
  • Access a key without checking if it exists
  • Ignore KeyError - it signals a real bug
  • Assume all keys are present in user data

Safe Access with .get()

What if you're not sure whether a key exists? Python provides the .get() method, which returns None (or a default value you specify) instead of raising an error:

1user = {"name": "Alice", "age": 28}
2
3# .get() returns None if missing
4email = user.get("email")
5print(email)
6
7# You can specify a default value
8status = user.get("status", "unknown")
9print(status)
10
11# Compare with existing key
12name = user.get("name", "Anonymous")
13print(name)
>>>Output
None
unknown
Alice
TIP
Use bracket notation [] when you know the key exists and want an error if it doesn't. Use .get() when the key might not exist and you want to handle that gracefully.
Fill in the blanks to safely access a missing key with a default value.
Python Quiz

> Look up the "city" key, which does not exist in this dictionary. Use the method that returns a default value instead of crashing.

user = {"name": "Alice", "age": 28}
city = user.___("city", ___)
print(city)
"Unknown"
find
pop
0
get
None

Now try the interactive version below. Pick the right access method for each blank and run the code to see how bracket notation and .get() behave differently with missing keys.

A KeyError from missing dict access is one of the most common runtime errors in Python data engineering. It almost always means you assumed a key would be present that was not, often because the data came from an external source like an API.
The .get() method is a defensive programming tool. Use it whenever you are processing data from outside your control: API responses, user input, configuration files, or database rows that might have optional fields.
Fill in the Blank

> A user dictionary contains only "name" and "age" keys, and you need to look up "city" which does not exist. Pick the access method that handles the missing key gracefully.

user = {"name": "Alice", "age": 28}
result = 
print(result)

Choosing between bracket access and .get() is a design decision about how your code should behave when data is missing. Bracket notation makes missing keys loud errors; .get() makes them silent defaults.

In production systems, .get() with a meaningful default is usually preferable. It keeps your pipeline running even when individual records have missing fields, and you can log or flag the missing data separately.

The in operator lets you check for key existence before access, which is another safe pattern. Use key in dict before bracket access when you want to take different actions depending on whether the key is present.

Adding and Updating Values

Daily Life
Interviews

Modify dict entries on the fly

Dictionaries are mutable, meaning you can change their contents after creation. Adding a new key-value pair and updating an existing value use the exact same syntax: assign to the key using bracket notation.
1user = {"name": "Alice", "age": 28}
2print("Before:", user)
3
4# Add a NEW key-value pair
5user["email"] = "alice@email.com"
6print("After adding email:", user)
7
8# Update an EXISTING value
9user["age"] = 29
10print("After updating age:", user)
>>>Output
Before: {'name': 'Alice', 'age': 28}
After adding email: {'name': 'Alice', 'age': 28, 'email': 'alice@email.com'}
After updating age: {'name': 'Alice', 'age': 29, 'email': 'alice@email.com'}
Notice that Python doesn't distinguish between adding and updating. If the key exists, the value gets replaced. If the key doesn't exist, it gets created. This is convenient but requires you to be careful about typos.

The Typo Trap

Because adding and updating use the same syntax, a typo in your key name silently creates a new entry instead of updating the intended one:
1user = {"name": "Alice", "email": "alice@email.com"}
2
3# Oops! Typo in the key name
4# Creates NEW key "emial" instead of updating "email"
5user["emial"] = "newemail@example.com"
6
7print(user)
8# Now you have both "email" and "emial"!
>>>Output
{'name': 'Alice', 'email': 'alice@email.com', 'emial': 'newemail@example.com'}
TIP
If your dictionary updates seem to "not work," check for typos. Unlike accessing a missing key (which raises KeyError), assigning to a misspelled key silently succeeds by creating a new entry.
Fill in the blanks to add a new entry and check how many key-value pairs the dictionary has.
Python Quiz

> Add an "email" entry to the user dictionary and update the "name" value. Then check how many entries the dictionary contains.

user = {"name": "Alice"}
user[___] = "alice@email.com"
user["name"] = "Bob"
print(___(user))
type
count
email
"email"
1
len

The fact that adding and updating use identical syntax is both a strength and a trap. It means you can always write dict[key] = value without checking first, but it also means typos silently create new keys rather than raising errors.

When you need to add multiple entries at once, the .update() method is more efficient than multiple individual assignments. Pass it another dictionary and all its entries will be merged into yours in a single operation.

Dictionaries are mutable, which means methods and functions can modify them in place. This is both powerful and dangerous. Be aware of whether a function you call might modify a dictionary you pass to it.

Removing Items

Daily Life
Interviews

Remove entries without crashing

Python provides several ways to remove items from a dictionary. Each method has slightly different behavior, so choosing the right one depends on what you need.

The del Statement

The del keyword removes a key-value pair from a dictionary. If the key doesn't exist, it raises a KeyError:

1user = {"name": "Alice", "age": 28, "city": "Seattle"}
2print("Before:", user)
3
4del user["city"]
5print("After del:", user)
>>>Output
Before: {'name': 'Alice', 'age': 28, 'city': 'Seattle'}
After del: {'name': 'Alice', 'age': 28}

The .pop() Method

The .pop() method removes a key and returns its value. This is useful when you need to both remove and use the value. You can also provide a default value to avoid errors if the key doesn't exist:

1user = {"name": "Alice", "age": 28, "city": "Seattle"}
2
3# Remove and get the value
4city = user.pop("city")
5print("Removed city:", city)
6print("Remaining:", user)
7
8# Safe pop with default (key doesn't exist)
9country = user.pop("country", "Unknown")
10print("Country:", country)
>>>Output
Removed city: Seattle
Remaining: {'name': 'Alice', 'age': 28}
Country: Unknown
del dict[key]
  • Just removes the entry
  • Raises KeyError if missing
  • Returns nothing (None)
  • More concise for simple removal
.pop(key)
  • Removes AND returns value
  • Can specify default value
  • More flexible and safe
  • Use when you need the value
Fill in the blanks to remove an entry and check the remaining dictionary size.
Python Quiz

> Remove the "city" entry from the dictionary and capture the removed value. Then check how many entries remain.

user = {
    "name": "Alice",
    "age": 28,
    "city": "Seattle"
}
removed = user.___("city")
print(removed)
print(___(user))
count
pop
len
del
remove
type

Clearing a Dictionary

To remove ALL items from a dictionary, use the .clear() method. This leaves you with an empty dictionary:

1settings = {"theme": "dark", "volume": 80, "notifications": True}
2print("Before:", settings)
3
4settings.clear()
5print("After clear:", settings)
6print("Length:", len(settings))
>>>Output
Before: {'theme': 'dark', 'volume': 80, 'notifications': True}
After clear: {}
Length: 0
Dictionary Removal Methods
  • del dict[key]: removes the pair, raises KeyError if missing
  • .pop(key): removes and returns the value
  • .pop(key, default): returns default if key is missing
  • .clear(): removes all entries, leaves empty dict
Choose the right removal method for the situation below. Think about what happens when the key might not exist.
Fill in the Blank

> You want to remove the "city" key from a user dictionary, but it might not be present. Pick the removal method that won't crash if the key is missing.

user = {"name": "Alice", "age": 28}
result = 
print(result)
print(user)

Removal operations are important for keeping dictionaries lean. In data pipelines, you often want to strip internal metadata keys before forwarding a record downstream, and .pop() lets you do that while capturing the removed value if needed.

Use .clear() when you want to reuse the same dictionary object but start fresh. This is more efficient than creating a new empty dictionary because existing references to the variable remain valid.

Always think about whether a key is guaranteed to exist before choosing between del, .pop(), and .pop(key, default). Defensive use of .pop() with a default prevents unexpected crashes from optional fields.

Checking for Keys

Daily Life
Interviews

Test key existence before access

Before accessing a key, you often want to check if it exists. The in operator checks whether a key is present in the dictionary:

1user = {"name": "Alice", "age": 28}
2
3# Check if key exists
4print("name" in user)
5print("email" in user)
6
7# Use in an if statement
8if "email" in user:
9 print("Email:", user["email"])
10else:
11 print("No email on file")
>>>Output
True
False
No email on file

This is the standard pattern for safely handling optional data. Check first with in, then access. Alternatively, use .get() with a default value as shown earlier.

Checking for Values

The in operator checks keys by default. To check if a VALUE exists in the dictionary, you need to explicitly use .values():

1user = {"name": "Alice", "age": 28, "city": "Seattle"}
2
3# Check if value exists (need .values())
4print("Alice" in user.values())
5print("Bob" in user.values())
6
7# Without .values(), it checks KEYS
8# False! "Alice" is a value, not a key
9print("Alice" in user)
>>>Output
True
False
False
TIP
Checking keys is very fast (near-instant regardless of dictionary size). Checking values with .values() is slower because Python must scan through all values. For large dictionaries, avoid frequent value lookups.

Dictionary Size

Just like with lists and strings, you can use len() to get the number of key-value pairs in a dictionary:

1empty = {}
2user = {"name": "Alice", "age": 28, "city": "Seattle"}
3
4print(len(empty))
5print(len(user))
6
7# Add an item and check again
8user["country"] = "USA"
9print(len(user))
>>>Output
0
3
4
Each key-value pair counts as one item. So a dictionary with 3 keys has a length of 3, regardless of how complex the values are.

What Can Be a Key?

Daily Life
Interviews

Choose valid key types confidently

Dictionary keys must be immutable (unchangeable) types. This is because Python uses a special technique called hashing to make key lookups extremely fast. Immutable types can be hashed; mutable types cannot.
Do
  • Strings: "name", "email" (most common)
  • Numbers: 1, 42, 3.14
  • Tuples: (1, 2) with immutable contents
  • Booleans: True, False
Don't
  • Lists: [1, 2, 3] are mutable
  • Dictionaries: {"a": 1} are mutable
  • Sets: {1, 2, 3} are mutable
  • Any other changeable type
1# Numbers as keys work fine
2scores = {1: "Gold", 2: "Silver", 3: "Bronze"}
3print(scores[1])
4
5# Mixed key types are allowed
6mixed = {"name": "Alice", 42: "answer", True: "yes"}
7print(mixed)
>>>Output
Gold
{'name': 'Alice', 42: 'answer', True: 'yes'}

Keys Must Be Unique

Each key in a dictionary must be unique. If you create a dictionary with duplicate keys, only the last value is kept:
1data = {"a": 1, "b": 2, "a": 3}
2print(data)
3
4# Only two entries, not three
5print(len(data))
>>>Output
{'a': 3, 'b': 2}
2
TIP
Python doesn't warn you about duplicate keys. It silently keeps the last one. Always review your dictionary definitions for accidental duplicates.

Real-World Use Cases

Daily Life
Interviews

Apply dicts to configs and counting

Dictionaries are everywhere in professional Python code. Here are some common patterns you'll encounter in real data engineering work:

Configuration Settings

Application configuration is almost always stored in dictionaries. This makes it easy to access settings by name:
1config = {
2 "database_host": "localhost",
3 "database_port": 5432,
4 "debug_mode": True,
5 "max_connections": 100
6}
7
8# Access settings by name
9print("Connecting to:", config["database_host"])
10print("Debug enabled:", config["debug_mode"])
>>>Output
Connecting to: localhost
Debug enabled: True

API Responses

When you call a web API, the response typically comes as JSON, which Python represents as nested dictionaries. Here's what weather API data might look like:
1weather = {
2 "city": "Seattle",
3 "temperature": 52,
4 "unit": "fahrenheit",
5 "conditions": "Cloudy"
6}
7
8print("Weather in " + weather["city"])
9print("Temperature:", weather["temperature"], weather["unit"])
10print("Conditions:", weather["conditions"])
>>>Output
Weather in Seattle
Temperature: 52 fahrenheit
Conditions: Cloudy

Counting Occurrences

Dictionaries are perfect for counting things. Use the item as the key and the count as the value:
1# Count word frequencies
2word_counts = {}
3words = ["apple", "banana", "apple", "cherry", "apple", "banana"]
4
5for word in words:
6 if word in word_counts:
7 word_counts[word] = word_counts[word] + 1
8 else:
9 word_counts[word] = 1
10
11print(word_counts)
>>>Output
{'apple': 3, 'banana': 2, 'cherry': 1}

Common Mistakes to Avoid

These mistakes are common when first learning dictionaries. Understanding why they happen will help you avoid frustrating debugging sessions.

Mistake 1: {} vs []

Curly braces create dictionaries (or sets), while square brackets create lists. Using the wrong one leads to confusing errors:
1# This creates a dictionary
2user = {"name": "Alice"}
3
4# This creates a list
5user_list = ["name", "Alice"]
6
7print(type(user))
8print(type(user_list))
>>>Output
<class 'dict'>
<class 'list'>

Mistake 2: = Instead of :

Inside dictionary literals, you use colons to separate keys from values, not equals signs:
1correct = {"name": "Alice", "age": 28}
2
3# wrong = {"name" = "Alice"}
4
5print(correct)
>>>Output
{'name': 'Alice', 'age': 28}

Mistake 3: Quotes on Keys

When your key is a string, you must include the quotes. Without quotes, Python thinks it's a variable name:
1# CORRECT: String keys need quotes
2correct = {"name": "Alice"}
3
4# This would look for a variable called 'name'
5# and cause NameError if it doesn't exist
6# wrong = {name: "Alice"}
7
8name_var = "username"
9dynamic = {name_var: "Alice"}
10print(dynamic)
>>>Output
{'username': 'Alice'}
Now put your debugging skills to the test. The code below has a syntax error in the dictionary definition. Remove the offending tile to fix it.
Debug Challenge

> This dictionary definition uses an equals sign instead of a colon for the first key-value pair, causing a SyntaxError.

SyntaxError: invalid syntax (expected : not =)

Dictionaries are fundamental to organizing and accessing data by meaningful keys. Put these fundamentals to the test with hands-on challenges in the Python Builder.
The patterns you have seen here - configuration dicts, API response dicts, and counting dicts - appear in virtually every Python project. Recognizing them quickly will make reading and writing real-world code feel natural.

As your data engineering skills grow, you will layer these basics with more advanced techniques like defaultdict for auto-initializing keys, Counter for frequency analysis, and dict comprehensions for concise transformations.

PUTTING IT ALL TOGETHER

> You are a data analyst at Stripe building a Python script that maps raw API field names to human-readable report headers, safely retrieves each mapping, updates labels when the API changes, removes deprecated fields, and checks membership before applying any rename transformation.

{} dict creation pairs each raw API field name with its display label in a structure that allows instant key-based lookup without scanning the whole mapping.
Accessing values with .get() safely retrieves each label without crashing when an unexpected API field name appears in the source data.
Updating a key's value with dict[key] = value refreshes a display label in place whenever the API renames an existing field.
Checking membership with in confirms a field exists in the mapping before attempting the rename, preventing KeyError at runtime.
KEY TAKEAWAYS
Dictionaries store key-value pairs, accessed by name instead of position
Use curly braces {} and colons : to create dictionaries
Access values with dict[key] or safely with .get(key, default)
Add/update with dict[key] = value; remove with del or .pop()
Check if a key exists with in
Keys must be immutable (strings, numbers, tuples) and unique
Dictionaries are ideal for structured data, configs, and counting

Key-value pairs power real-world data

Category
Python
Difficulty
beginner
Duration
34 minutes
Challenges
3 hands-on challenges

Topics covered: What is a Dictionary?, Creating Dictionaries, Accessing Values, Adding and Updating Values, Removing Items, Checking for Keys, What Can Be a Key?, Real-World Use Cases

Lesson Sections

  1. What is a Dictionary? (concepts: pyDictCreate)

    A dictionary in Python is a collection that stores data as key-value pairs. Instead of accessing items by their position (like in a list), you access them by their key. The key is a unique identifier, and the value is whatever data you want to associate with that key. The Real Dictionary Analogy The name "dictionary" comes from actual word dictionaries. In a physical dictionary, you look up a word (the key) to find its definition (the value). You don't say "give me the 4,532nd word." You say "gi

  2. Creating Dictionaries

    Python uses curly braces {} to create dictionaries. Inside the braces, you write key-value pairs separated by colons. Multiple pairs are separated by commas. Let's revisit that user profile problem with a dictionary: Now your data is self-documenting. Anyone reading this code immediately understands what each piece of data represents. The key "name" tells you it's a name. The key "age" tells you it's an age. No memorization required. Syntax Breakdown Understanding the syntax elements helps you r

  3. Accessing Values (concepts: pyDictMethods)

    To retrieve a value from a dictionary, you use square brackets with the key inside. This looks similar to list indexing, but instead of a number, you provide the key name: This is the fundamental operation that makes dictionaries powerful. You're saying "give me the value associated with this key" rather than "give me the value at this position." Handling Missing Keys If you try to access a key that doesn't exist, Python raises a KeyError. This is different from lists, where accessing an invalid

  4. Adding and Updating Values

    Dictionaries are mutable, meaning you can change their contents after creation. Adding a new key-value pair and updating an existing value use the exact same syntax: assign to the key using bracket notation. Notice that Python doesn't distinguish between adding and updating. If the key exists, the value gets replaced. If the key doesn't exist, it gets created. This is convenient but requires you to be careful about typos. The Typo Trap Because adding and updating use the same syntax, a typo in y

  5. Removing Items

    Python provides several ways to remove items from a dictionary. Each method has slightly different behavior, so choosing the right one depends on what you need. The del Statement The .pop() Method Fill in the blanks to remove an entry and check the remaining dictionary size. Clearing a Dictionary Choose the right removal method for the situation below. Think about what happens when the key might not exist.

  6. Checking for Keys

    Checking for Values Dictionary Size Each key-value pair counts as one item. So a dictionary with 3 keys has a length of 3, regardless of how complex the values are.

  7. What Can Be a Key?

    Dictionary keys must be immutable (unchangeable) types. This is because Python uses a special technique called hashing to make key lookups extremely fast. Immutable types can be hashed; mutable types cannot. Keys Must Be Unique Each key in a dictionary must be unique. If you create a dictionary with duplicate keys, only the last value is kept:

  8. Real-World Use Cases

    Dictionaries are everywhere in professional Python code. Here are some common patterns you'll encounter in real data engineering work: Configuration Settings Application configuration is almost always stored in dictionaries. This makes it easy to access settings by name: API Responses When you call a web API, the response typically comes as JSON, which Python represents as nested dictionaries. Here's what weather API data might look like: Counting Occurrences Dictionaries are perfect for countin