How to access a dictionary in Python

Learn the different ways to access a Python dictionary. Find tips, real-world applications, and solutions for common errors.

How to access a dictionary in Python
Published on: 
Thu
Feb 12, 2026
Updated on: 
Tue
Feb 24, 2026
The Replit Team Logo Image
The Replit Team

Python dictionaries are fundamental data structures that store key-value pairs. You can access their data with several straightforward methods, each suited for different programming needs and scenarios.

In this article, you'll learn techniques to retrieve values from your dictionaries. You'll find practical tips for efficient lookups, see real-world applications, and learn how to debug common errors you might encounter.

Basic dictionary access with square brackets

student = {'name': 'Alice', 'age': 22, 'courses': ['Math', 'CS']}
print(student['name'])
print(student['courses'][1])--OUTPUT--Alice
CS

The most direct way to get a value from a dictionary is by using square brackets [] with the key. This method is fast and straightforward for simple lookups where you're certain the key exists. In the example, student['name'] looks up the key 'name' and returns its value, 'Alice'.

You can also chain accessors to navigate nested data structures. The expression student['courses'][1] first retrieves the list associated with the 'courses' key and then accesses the element at index 1 within that list, which is 'CS'. Just be aware that this direct approach will raise a KeyError if a key isn't found.

Common dictionary operations

While square brackets are great for simple access, Python provides more robust tools for safely getting values, iterating over contents, and navigating complex nested structures.

Using the get() method for safer access

student = {'name': 'Alice', 'age': 22}
print(student.get('name'))
print(student.get('grade', 'Not Found')) # Provides default value if key doesn't exist--OUTPUT--Alice
Not Found

The get() method provides a safer way to access dictionary values because it won't raise a KeyError if a key is missing. This makes your code more resilient, especially when dealing with unpredictable data. Instead, it gracefully handles missing keys by returning a default value.

  • If the key exists, get() returns the corresponding value, just like square bracket access.
  • If the key doesn't exist, it returns None by default.
  • You can also provide a second argument to specify a custom default value, as seen with student.get('grade', 'Not Found').

Accessing keys, values, and items

student = {'name': 'Alice', 'age': 22, 'major': 'Computer Science'}
print(list(student.keys()))
print(list(student.values()))
print(list(student.items()))--OUTPUT--['name', 'age', 'major']
['Alice', 22, 'Computer Science']
[('name', 'Alice'), ('age', 22), ('major', 'Computer Science')]

When you need to work with a dictionary's contents in bulk, Python offers three useful methods. These methods return dynamic "view objects," which is why the example code converts them to lists using list() to print them. This approach is perfect for loops or comprehensions.

  • keys() returns a view of all the dictionary's keys.
  • values() provides a view of all the values.
  • items() gives you a view of all key-value pairs, structured as (key, value) tuples.

Working with nested dictionaries

person = {
'name': 'Bob',
'address': {
'city': 'New York',
'zip': 10001
}
}
print(person['address']['city'])
print(f"{person['name']} lives in {person['address']['city']}")--OUTPUT--New York
Bob lives in New York

Dictionaries aren't limited to simple values; they can contain other dictionaries, creating nested structures. In the example, the value for the 'address' key is another dictionary. To access data deep inside, you can chain square bracket accessors together.

  • The expression person['address']['city'] first retrieves the inner address dictionary, then gets the value for the 'city' key from it.

This technique is especially useful when working with structured data formats like JSON. You can easily pull specific pieces of information from complex objects to use in your program.

Advanced dictionary techniques

Building on the fundamentals, you can use more advanced tools like dictionary comprehensions, defaultdict, and the | operator to transform and manage your data efficiently.

Dictionary comprehensions for transformation

prices = {'apple': 0.5, 'banana': 0.25, 'orange': 0.75}
doubled_prices = {fruit: price * 2 for fruit, price in prices.items()}
filtered_prices = {k: v for k, v in prices.items() if v > 0.3}
print(doubled_prices)
print(filtered_prices)--OUTPUT--{'apple': 1.0, 'banana': 0.5, 'orange': 1.5}
{'apple': 0.5, 'orange': 0.75}

Dictionary comprehensions offer a concise way to create new dictionaries from existing ones. They're a powerful tool for transforming and filtering data without writing lengthy for loops, making your code more readable and efficient.

  • The doubled_prices dictionary is created by iterating over prices.items() and applying an operation—multiplying each price by two.
  • In filtered_prices, a conditional is added. The comprehension builds a new dictionary by including only the items from prices where the value is greater than 0.3.

Using defaultdict to handle missing keys

from collections import defaultdict
fruit_count = defaultdict(int)
fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
for fruit in fruits:
fruit_count[fruit] += 1
print(dict(fruit_count))--OUTPUT--{'apple': 3, 'banana': 2, 'orange': 1}

The defaultdict from the collections module is a handy tool for counting or grouping items because it automatically handles missing keys. This prevents the KeyError you'd normally get when trying to access a key that doesn't exist yet.

  • When you initialize a defaultdict(int), you're telling it that if a key is accessed for the first time, its value should default to 0.
  • This allows you to use an operation like fruit_count[fruit] += 1 directly, without needing to check if the key exists first.

Merging dictionaries with the | operator

user_info = {'name': 'Charlie', 'age': 30}
additional_info = {'job': 'Developer', 'city': 'San Francisco'}
complete_info = user_info | additional_info
print(complete_info)--OUTPUT--{'name': 'Charlie', 'age': 30, 'job': 'Developer', 'city': 'San Francisco'}

The pipe | operator offers a clean, modern way to merge two dictionaries. Introduced in Python 3.9, it combines the key-value pairs from both dictionaries into a new one, leaving the original dictionaries untouched. This is a concise alternative to older methods like using the update() function.

  • The expression user_info | additional_info creates a new dictionary containing all items from both.
  • If both dictionaries happen to share a key, the value from the right-hand dictionary—in this case, additional_info—will overwrite the one from the left.

Move faster with Replit

Replit is an AI-powered development platform that transforms natural language into working applications. Describe what you want to build, and Replit Agent creates it—complete with databases, APIs, and deployment.

For the dictionary techniques we've explored, Replit Agent can turn them into production-ready applications:

  • Build a log analyzer that uses a defaultdict to count error types from structured log files.
  • Create a configuration manager that safely retrieves settings from nested dictionaries with the get() method.
  • Deploy a data filtering tool that uses dictionary comprehensions to process and transform JSON data based on user-defined criteria.

Describe your app idea, and Replit Agent will write the code, test it, and fix issues automatically, all in your browser.

Common errors and challenges

Even with the right tools, you might run into a few common pitfalls when accessing dictionary data, from `KeyError` exceptions to unexpected modifications.

Handling KeyError when accessing non-existent keys

The most frequent issue is the KeyError. This error stops your program when you try to access a key with square brackets [] that isn't in the dictionary. While direct access is fast, it assumes the key always exists.

You can prevent this crash by checking for a key's existence with the in operator before you try to access it. A more direct solution is to use the get() method, which returns None or a specified default value if the key is missing, keeping your code running smoothly.

Avoiding errors when modifying dictionaries during iteration

Modifying a dictionary while you're looping over it is a classic mistake that can cause a RuntimeError. Python doesn't allow you to change the size of a dictionary while iterating through it because it leads to unpredictable behavior.

To safely add or remove items, you should iterate over a static copy of the keys, values, or items. You can create a copy easily, for example, by wrapping the keys() method in a list like this: list(my_dict.keys()). This lets you loop over the copy while safely modifying the original dictionary.

Understanding dictionary reference behavior

It's also crucial to understand how Python handles dictionary assignments. When you write new_dict = old_dict, you aren't creating a new dictionary. Instead, you're creating a second reference that points to the exact same dictionary in memory.

  • This means any change you make to new_dict will also affect old_dict, which can lead to surprising bugs.
  • If your goal is to create an independent duplicate, you should make an explicit copy. You can do this with the copy() method or by using a dictionary comprehension to build a new dictionary from the original's items.

Handling KeyError when accessing non-existent keys

Directly accessing a non-existent key with square brackets [] is a surefire way to trigger a KeyError and crash your program. The following example demonstrates this common pitfall by attempting to retrieve a 'phone' key that isn't in the dictionary.

user_data = {'name': 'John', 'email': '[email protected]'}
# This will raise a KeyError
phone = user_data['phone']
print(f"User's phone: {phone}")

The code fails because it directly tries to access the 'phone' key, which isn't present in the dictionary. This causes an immediate KeyError. The following example shows a more robust way to handle this lookup.

user_data = {'name': 'John', 'email': '[email protected]'}
# Using get() method with a default value
phone = user_data.get('phone', 'Not provided')
print(f"User's phone: {phone}")

The corrected code avoids the KeyError by using the get() method. Instead of crashing, user_data.get('phone', 'Not provided') checks for the 'phone' key. Since it doesn't find it, the method returns the default value you specified—in this case, 'Not provided'. This approach is ideal when you're working with data where keys aren't guaranteed to be present, such as parsing optional fields from a JSON file or handling user form submissions.

Avoiding errors when modifying dictionaries during iteration

It's tempting to remove items from a dictionary directly within a loop, but this will crash your program with a RuntimeError. Python's iterators can't handle changes to the dictionary's size mid-loop. See this common error in action in the example below.

scores = {'Alice': 85, 'Bob': 45, 'Charlie': 92, 'Dave': 38}
# This will raise RuntimeError: dictionary changed size during iteration
for name, score in scores.items():
if score < 50:
del scores[name]
print(scores)

The loop attempts to remove an item with del scores[name] while iterating over the same dictionary, causing the RuntimeError. The corrected code below shows how to safely modify the dictionary without this conflict.

scores = {'Alice': 85, 'Bob': 45, 'Charlie': 92, 'Dave': 38}
# Create a new dictionary instead of modifying during iteration
passing_scores = {name: score for name, score in scores.items() if score >= 50}
print(passing_scores)

The corrected code avoids the RuntimeError by building an entirely new dictionary instead of changing the original during iteration. A dictionary comprehension creates passing_scores, including only the items that meet the condition. This is the standard, Pythonic way to filter a dictionary because it prevents errors and unwanted side effects. You should use this approach whenever you need to remove items from a dictionary based on a condition while looping.

Understanding dictionary reference behavior

A common source of bugs is mistaking a dictionary assignment for a copy. When you use the = operator, both variables point to the same dictionary, so modifying one affects the other. The following code shows how this can lead to unintended side effects.

original = {'name': 'Alice', 'scores': [85, 90, 78]}
duplicate = original # This doesn't create a new copy
duplicate['name'] = 'Bob' # Modifies both dictionaries!
print(f"Original: {original}")
print(f"Duplicate: {duplicate}")

Because duplicate is just another name for original, changing the name to 'Bob' modifies both dictionaries. This side effect can introduce hard-to-find bugs. The following example shows how to create a truly independent copy.

import copy
original = {'name': 'Alice', 'scores': [85, 90, 78]}
duplicate = copy.deepcopy(original) # Creates independent copy
duplicate['name'] = 'Bob' # Only modifies the duplicate
print(f"Original: {original}")
print(f"Duplicate: {duplicate}")

The corrected code uses copy.deepcopy() to create a completely independent duplicate of the original dictionary. Now, when you change the name in the duplicate, the original dictionary remains untouched. It's essential when you need to modify data without causing side effects. Use deepcopy() whenever your dictionary contains mutable objects like lists or other dictionaries to ensure they’re copied too, preventing unexpected changes to your original data structure.

Real-world applications

Now that you can confidently access dictionary data, you can apply these skills to build practical tools for text analysis and menu systems.

Using dictionaries for word frequency analysis

You can easily build a word frequency counter by using a dictionary to map each word from a text to its running count.

text = "the quick brown fox jumps over the lazy dog"
word_count = {}
for word in text.lower().split():
word_count[word] = word_count.get(word, 0) + 1
print(word_count)
print(f"Most frequent word: {max(word_count, key=word_count.get)}")

This snippet builds a frequency map by looping through each word in the lowercase text. The expression word_count.get(word, 0) + 1 efficiently updates the count for each word, starting new words at one.

  • The final dictionary maps each unique word to its total count.
  • To find the most frequent word, max() is used with key=word_count.get. This instructs max() to evaluate the keys based on their corresponding values, returning the word with the highest count.

Building a data-driven menu system with dict as a command dispatcher

A dictionary can also serve as a clean command dispatcher, mapping user input strings directly to the functions that should run.

def show_help():
return "Displaying help information"

def process_order():
return "Processing your order"

commands = {
'help': show_help,
'order': process_order
}

user_input = 'help'
result = commands.get(user_input, lambda: "Invalid command")()
print(result)

This example shows how you can store functions directly as values within a dictionary. The commands dictionary maps string keys to the show_help and process_order functions themselves, not their results.

  • The get() method retrieves the function object corresponding to the user_input string.
  • The parentheses () at the end of the line immediately execute whichever function is returned.
  • If the input is invalid, a default lambda function runs instead, preventing an error and making the code more robust.

Get started with Replit

Turn your knowledge into a real tool. Describe what you want to build to Replit Agent, like "a script that counts word frequencies from a text file" or "an app that extracts user emails from JSON data."

The agent will write the code, test for errors, and deploy your app. You just provide the idea. Start building with Replit.

Get started free

Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.

Get started for free

Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.