Table of contents
Implement code functionality

How to append to a dictionary in Python

May 30, 2025
 ・ by  
Claude and the Anthropic Team
Table of contents
H2 Link Template
Try Claude

Python dictionaries store key-value pairs that let you organize and access data efficiently. Adding new entries requires understanding the different methods available, from basic assignment with = to specialized dictionary methods.

This guide covers essential techniques for dictionary manipulation, with practical examples and troubleshooting tips created using Claude, an AI assistant built by Anthropic.

Adding a key-value pair to a dictionary

student = {"name": "John", "age": 21}
student["grade"] = "A"
print(student)
{'name': 'John', 'age': 21, 'grade': 'A'}

The square bracket syntax student["grade"] = "A" directly assigns a new key-value pair to the dictionary. This approach offers more flexibility than other methods since it works with any valid key type—not just strings.

Square bracket assignment provides these key advantages:

  • Dynamically creates the key if it doesn't exist
  • Updates the value if the key already exists
  • Allows for variable keys and computed expressions

This straightforward method remains the most common way to add dictionary entries in Python. It maintains readable code while giving you full control over key-value manipulation.

Common dictionary update techniques

Beyond basic square bracket assignment, Python offers powerful methods like update(), ** unpacking, and dictionary comprehensions to efficiently combine and extend dictionaries.

Using the update() method to add multiple items

car = {"make": "Toyota", "model": "Corolla"}
car.update({"year": 2022, "color": "blue"})
print(car)
{'make': 'Toyota', 'model': 'Corolla', 'year': 2022, 'color': 'blue'}

The update() method efficiently adds multiple key-value pairs to a dictionary in a single operation. Unlike individual assignments, you can pass an entire dictionary as an argument to merge its contents with the target dictionary.

  • Updates existing keys with new values if there are conflicts
  • Preserves the original key-value pairs that don't overlap
  • Accepts various input formats including dictionaries, keyword arguments, and iterables of key-value pairs

In the example, car.update() adds both the year and color simultaneously to the original dictionary containing make and model. This approach streamlines code when you need to incorporate multiple related values at once.

Using dictionary unpacking with ** operator

fruits = {"apple": 5, "banana": 3}
more_fruits = {"orange": 2, "grape": 4}
all_fruits = {**fruits, **more_fruits}
print(all_fruits)
{'apple': 5, 'banana': 3, 'orange': 2, 'grape': 4}

The double asterisk operator ** merges multiple dictionaries into a new one. This unpacking syntax creates a clean, readable way to combine dictionaries without modifying the originals.

  • The expression {**fruits, **more_fruits} creates a new dictionary by unpacking both source dictionaries
  • Python processes the unpacking from left to right. If duplicate keys exist, the rightmost value wins
  • The operation preserves the original dictionaries fruits and more_fruits unchanged

Dictionary unpacking offers a more elegant alternative to update() when you need to merge dictionaries without side effects. This approach particularly shines when combining three or more dictionaries in a single expression.

Merging dictionaries with dictionary comprehensions

dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
merged = {k: dict2.get(k, dict1.get(k)) for k in set(dict1) | set(dict2)}
print(merged)
{'a': 1, 'b': 3, 'c': 4}

Dictionary comprehensions provide a concise way to merge dictionaries while controlling how overlapping keys combine. The expression set(dict1) | set(dict2) creates a union of all unique keys from both dictionaries.

  • The get() method safely retrieves values with a fallback option if the key isn't found
  • When processing each key, the code first checks dict2. If the key isn't there, it falls back to dict1
  • This approach gives dict2 priority for duplicate keys. In the example, b takes the value 3 from dict2 instead of 2 from dict1

This method offers more control over value selection compared to dictionary unpacking. You can easily modify the comprehension logic to implement custom merging rules based on your needs.

Advanced dictionary techniques

Python's specialized dictionary tools like defaultdict, setdefault(), and ChainMap unlock powerful ways to handle nested data structures and manage dictionary hierarchies with minimal code.

Using collections.defaultdict for nested dictionaries

from collections import defaultdict
user_scores = defaultdict(dict)
user_scores["Alice"]["math"] = 95
user_scores["Alice"]["science"] = 92
print(dict(user_scores))
{'Alice': {'math': 95, 'science': 92}}

defaultdict automatically creates a new dictionary when you access a non-existent key. This eliminates the need to manually check and initialize nested dictionaries, making your code cleaner and more efficient.

  • The argument passed to defaultdict(dict) specifies the default factory function that creates the nested dictionary structure
  • When you access user_scores["Alice"] for the first time, it automatically creates an empty dictionary instead of raising a KeyError
  • This behavior enables direct nested assignments like user_scores["Alice"]["math"] = 95 without additional setup code

Regular dictionaries would require explicit initialization of the nested structure before assignment. defaultdict handles this automatically, reducing boilerplate code and potential errors in your data structure management.

Using setdefault() to append with a default value

contacts = {"John": ["555-1234"]}
contacts.setdefault("John", []).append("555-5678")
contacts.setdefault("Mary", []).append("555-9012")
print(contacts)
{'John': ['555-1234', '555-5678'], 'Mary': ['555-9012']}

The setdefault() method provides a clean way to handle dictionary values that need default initialization. It returns the value for a given key if it exists. If the key doesn't exist, it creates the key with the specified default value and returns that value.

  • When adding a second phone number for John, setdefault() returns the existing list ["555-1234"]. The append() then adds the new number to this list
  • For Mary's entry, setdefault() first creates a new empty list since the key doesn't exist. Then append() adds the phone number to this new list

This approach eliminates the need for explicit key existence checks and separate initialization steps. You can safely append values without worrying whether the key already exists in the dictionary.

Using ChainMap for dictionary views

from collections import ChainMap
defaults = {"theme": "dark", "language": "en"}
user_settings = {"theme": "light"}
settings = ChainMap(user_settings, defaults)
print(dict(settings))
{'theme': 'light', 'language': 'en'}

ChainMap creates a view of multiple dictionaries in a specified priority order. When you look up a key, it searches through the dictionaries in sequence until it finds a match. This makes it perfect for implementing layered configurations like settings with defaults.

  • The first dictionary (user_settings) takes precedence. Any matching keys here override values from later dictionaries
  • If a key isn't found in the first dictionary, ChainMap checks subsequent dictionaries in order
  • The original dictionaries remain unchanged. ChainMap simply provides a unified view

In the example, theme comes from user_settings while language falls back to the value in defaults. This creates an elegant solution for managing configuration hierarchies without complex conditional logic.

Get unstuck faster with Claude

Claude is an AI assistant created by Anthropic that helps developers write better code and solve programming challenges. It combines deep technical knowledge with natural conversation to guide you through complex Python concepts like the dictionary techniques covered above.

Working alongside Claude feels like having an experienced mentor who can explain nuanced topics, debug tricky issues, and suggest optimal approaches. It helps you understand not just how to use methods like ChainMap and defaultdict, but also when and why to apply them in your code.

Start building better Python applications today with personalized guidance from an AI that understands your code. Sign up for free at Claude.ai to get unstuck faster and take your development skills to the next level.

Some real-world applications

Building on the dictionary techniques we've explored, Python dictionaries power essential real-world applications from text analysis to optimizing complex algorithms.

Text analysis with a dict frequency counter

Dictionaries excel at tracking word frequencies in text analysis by using the get() method to safely increment counters without explicit initialization checks.

text = "to be or not to be that is the question"
word_freq = {}
for word in text.split():
    word_freq[word] = word_freq.get(word, 0) + 1
print(word_freq)

This code creates a dictionary that counts how many times each word appears in a text string. The split() method breaks the string into individual words. For each word, the code uses get() to either retrieve its current count or return 0 if the word isn't in the dictionary yet.

  • The get() method's second parameter (0) serves as a default value
  • Adding 1 to this value updates the count for each word occurrence
  • The word_freq[word] = assignment stores the new count back in the dictionary

This pattern efficiently handles both new and existing words in a single line. The final dictionary will show each unique word as a key with its frequency as the value.

Creating a memoization cache with dict for recursive functions

Dictionaries serve as powerful caching tools to speed up recursive functions by storing previously calculated results—a technique called memoization that prevents redundant computations.

cache = {}
def fibonacci(n):
    if n in cache:
        return cache[n]
    if n <= 1:
        result = n
    else:
        result = fibonacci(n-1) + fibonacci(n-2)
    cache[n] = result
    return result

print(fibonacci(6))
print("Cache:", cache)

This implementation of the fibonacci() function uses a dictionary called cache to store previously calculated Fibonacci numbers. When calculating fibonacci(6), the function first checks if the result exists in the cache. If not found, it recursively calculates the value using the standard Fibonacci formula.

  • The if n in cache check prevents redundant calculations by returning cached results immediately
  • Each new calculation gets stored in the cache with cache[n] = result
  • Base cases (n <= 1) return n directly

This caching strategy dramatically improves performance by avoiding repeated computations of the same Fibonacci numbers during recursion. Each number only needs to be calculated once.

Common errors and challenges

Python dictionaries can trigger subtle errors when modifying data structures, from missing keys to iteration conflicts and nested data complexities.

Avoiding KeyError when accessing non-existent keys

Accessing dictionary keys that don't exist triggers Python's KeyError exception. This common pitfall occurs when developers directly reference keys without first verifying their presence in the dictionary. The code below demonstrates how attempting to access a non-existent phone key leads to a runtime error.

user_data = {"name": "Alice", "email": "alice@example.com"}
phone = user_data["phone"]  # This raises KeyError: 'phone'
print(f"Phone number: {phone}")

The code attempts to directly access the phone key without first checking if it exists in user_data. Python immediately halts execution when it can't find the requested key. Let's examine a safer approach in the next example.

user_data = {"name": "Alice", "email": "alice@example.com"}
phone = user_data.get("phone", "Not available")
print(f"Phone number: {phone}")

The get() method provides a safer way to access dictionary values by accepting a default fallback value. When Python can't find the requested key, it returns this default instead of raising an error. This approach maintains smooth code execution while handling missing data gracefully.

  • Watch for direct key access with square brackets in code that processes user input or external data
  • Consider using get() whenever a key's existence is uncertain
  • Choose meaningful default values that help debug issues or provide useful feedback

The example demonstrates this by returning "Not available" when the phone number doesn't exist. This pattern proves especially valuable when processing data from APIs or user forms where missing fields are common.

Preventing dictionary modification errors during iteration

Modifying a Python dictionary while iterating through it can trigger runtime errors or produce unexpected results. The code below demonstrates a common mistake where adding new key-value pairs during a for loop creates unpredictable behavior.

scores = {"math": 90, "science": 95, "history": 85}
for subject in scores:
    if scores[subject] > 90:
        scores["honors_" + subject] = True  # Modifies dict during iteration
print(scores)

Python's dictionary size changes when the loop adds new honors_ entries. This disrupts the iterator's internal tracking of dictionary elements. The following code demonstrates a safer approach to handle this scenario.

scores = {"math": 90, "science": 95, "history": 85}
honors_subjects = {}
for subject in scores:
    if scores[subject] > 90:
        honors_subjects["honors_" + subject] = True
scores.update(honors_subjects)  # Updates after iteration completes
print(scores)

The solution creates a temporary dictionary honors_subjects to store new entries while iterating through the original scores dictionary. This approach prevents runtime errors by separating the iteration and modification steps.

  • Store new key-value pairs in a separate dictionary during iteration
  • Use update() to merge changes after the loop completes
  • Watch for this pattern when your code needs to add or modify dictionary entries based on existing values

This error commonly occurs in data processing tasks where you need to derive new values from existing dictionary entries. Always consider creating a separate dictionary for new entries when your loop logic involves dictionary modifications.

Understanding nested dictionary copying issues

Python's standard dictionary copying methods can produce unexpected behavior with nested data structures. The copy() method creates a shallow copy that still references nested objects in memory. This leads to unintended modifications when working with nested dictionaries or lists. Let's examine this behavior in the code below.

import copy
original = {"user": {"name": "John", "scores": [85, 90]}}
copied = original.copy()  # Creates shallow copy
copied["user"]["scores"][0] = 100  # Modifies original too!
print(original["user"]["scores"])  # Shows [100, 90]

The shallow copy creates a new dictionary that still points to the same nested objects in memory. When you modify nested data in the copied version, those changes affect both dictionaries since they share references. The next code example demonstrates the proper solution.

import copy
original = {"user": {"name": "John", "scores": [85, 90]}}
copied = copy.deepcopy(original)  # Creates deep copy
copied["user"]["scores"][0] = 100  # Only affects the copy
print(original["user"]["scores"])  # Still shows [85, 90]

The copy.deepcopy() function creates a completely independent copy of nested dictionaries by recursively duplicating all nested objects. This prevents unintended modifications to the original data structure when you change values in the copy.

  • Watch for this issue when working with dictionaries containing lists, other dictionaries, or complex objects as values
  • Regular dictionary methods like dict.copy() or the {} operator only create shallow copies that share references to nested objects
  • Use deepcopy() when you need to modify nested data without affecting the source dictionary

This pattern commonly appears in data processing pipelines where you need to transform nested structures while preserving the original data for later use or comparison.

Learning or leveling up? Use Claude

Anthropic's Claude combines sophisticated programming expertise with intuitive communication abilities to help you master Python concepts and solve coding challenges. This AI assistant excels at breaking down complex topics into clear, actionable steps while suggesting optimal approaches based on your specific needs.

Here are some prompts you can use to explore Python dictionaries with Claude:

  • Dictionary basics: Ask "What's the difference between dict.update() and dict.setdefault()?" and Claude will explain their distinct use cases and provide examples.
  • Error handling: Ask "How do I safely handle missing dictionary keys?" and Claude will demonstrate various approaches using get() and exception handling.
  • Performance optimization: Ask "What's the most efficient way to merge multiple dictionaries?" and Claude will compare different methods with their performance implications.
  • Real-world application: Ask "Show me how to build a word frequency counter using dictionaries" and Claude will guide you through a practical implementation.

Experience personalized coding assistance by signing up for free at Claude.ai.

For a more integrated development experience, Claude Code brings AI assistance directly into your terminal, enabling seamless collaboration while you write and debug Python code.

FAQs

Additional Resources

How to reverse a list in Python

2025-05-22
14 min
 read
Read more

How to print a matrix in Python

2025-05-30
14 min
 read
Read more

How to clear the screen in Python

2025-05-30
14 min
 read
Read more

Leading companies build with Claude

ReplitCognitionGithub CopilotCursorSourcegraph
Try Claude
Get API Access
Copy
Expand