W3docs

Python Dictionaries: Copy Method Explained

Learn every way to copy a Python dictionary — copy(), dict(), {**d}, and deepcopy() — with clear examples showing shallow vs. deep copy behaviour.

This chapter explains every standard way to copy a Python dictionary, why a plain assignment (=) is not a copy, and when you need a deep copy instead of a shallow one.

Why You Cannot Copy a Dictionary with =

Assigning a dictionary to a new variable does not create a copy — it creates a second reference to the same object. Any change made through either variable affects the same underlying dictionary.

original = {'a': 1, 'b': 2}
alias = original          # same object, not a copy

alias['c'] = 3
print(original)           # {'a': 1, 'b': 2, 'c': 3}  — original changed!

To get a genuinely independent dictionary you need one of the copy methods shown below.

Shallow Copy vs. Deep Copy

Before looking at the methods, it helps to understand the two kinds of copy:

KindWhat is copiedNested mutables
Shallow copyTop-level key-value pairsReferences are shared — mutation in one dict affects the other
Deep copyEvery object at every depthFully independent — no shared references

For flat dictionaries (values are strings, numbers, None, booleans) a shallow copy is always sufficient. For dictionaries that contain lists, sets, or other dictionaries as values, consider a deep copy.

Method 1: dict.copy()

The built-in copy() method returns a new dictionary that is a shallow copy of the original. It is the most idiomatic choice for flat dictionaries.

Syntax

new_dict = original_dict.copy()

Make a shallow copy of a dictionary in Python

python— editable, runs on the server

Adding or removing a key in new_dict leaves original_dict untouched because the top-level copy is independent.

Updating top-level keys in a copied dictionary

python— editable, runs on the server

Method 2: dict() Constructor

Passing an existing dictionary to the dict() constructor creates a shallow copy in the same way as copy().

original_dict = {'name': 'Alice', 'age': 30}
new_dict = dict(original_dict)

new_dict['age'] = 31
print(original_dict)   # {'name': 'Alice', 'age': 30}
print(new_dict)        # {'name': 'Alice', 'age': 31}

dict() is useful when you want to be explicit about creating a dictionary from another mapping or when you mix keyword arguments with an existing dictionary:

defaults = {'color': 'blue', 'size': 'M'}
custom = dict(defaults, size='L', weight='light')
print(custom)
# {'color': 'blue', 'size': 'L', 'weight': 'light'}

Method 3: Dictionary Unpacking {**d}

The ** unpacking operator merges a dictionary into a new dictionary literal. For a simple copy it behaves identically to copy(), but it also lets you merge several dictionaries or override individual keys in one expression.

original_dict = {'a': 1, 'b': 2}
new_dict = {**original_dict}

new_dict['c'] = 3
print(original_dict)   # {'a': 1, 'b': 2}
print(new_dict)        # {'a': 1, 'b': 2, 'c': 3}

Copying while overriding a key

config = {'host': 'localhost', 'port': 5432, 'debug': False}
prod_config = {**config, 'host': 'db.example.com', 'debug': False}
print(prod_config)
# {'host': 'db.example.com', 'port': 5432, 'debug': False}

Like copy(), this is a shallow copy — nested mutables are still shared.

Shallow Copy Gotcha: Nested Mutables Are Shared

All three methods above produce shallow copies. When a value is itself a mutable object (such as a list), both the original and the copy hold a reference to the same inner object.

Updating mutable values inside a copied dictionary

python— editable, runs on the server

Both dictionaries reflect the change because new_dict['key1'] and original_dict['key1'] point to the same list object. This is expected behaviour for a shallow copy — it is not a bug.

Method 4: copy.deepcopy() for Full Independence

When you need complete isolation — including nested lists, sets, and dictionaries — use copy.deepcopy() from the standard-library copy module. It recursively copies every object in the structure.

Deep copy in Python

python— editable, runs on the server

deepcopy() handles arbitrarily nested structures and even self-referential objects. Its trade-off is speed and memory: it is slower than a shallow copy because it must traverse and duplicate the entire object graph.

Choosing the Right Method

SituationRecommended method
Flat dictionary (no nested mutables)dict.copy() or {**d}
Merge / override keys while copying{**d, key: value} or dict(d, key=value)
Nested mutables, need full independencecopy.deepcopy()
Convert another mapping to a dict copydict(mapping)

Summary

  • The = operator creates an alias, not a copy.
  • dict.copy(), dict(), and {**d} all produce shallow copies — top-level keys are independent but nested mutables are shared.
  • copy.deepcopy() produces a deep copy — every object at every depth is duplicated.
  • For flat dictionaries, prefer dict.copy() for clarity.
  • Use {**d, overrides} when you need to copy and modify in a single expression.

See also: Dictionary Methods · Nested Dictionaries · Loop Through Dictionaries

Practice

Practice
Which of the following methods can be used to copy Python Dictionaries?
Which of the following methods can be used to copy Python Dictionaries?
Was this page helpful?