๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ copy.html
copy โ€” Shallow and deep copy operations
Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.
๐ŸŒ
The Python Coding Book
thepythoncodingbook.com โ€บ home โ€บ blog โ€บ shallow and deep copy in python and how to use __copy__()
Shallow and Deep Copy in Python and How to Use __copy__()
November 12, 2023 - The article explores shallow and deep copy in Python, and how to use the __copy__() dunder method to customise the copying behaviour
Discussions

oop - How can I create a copy of an object in Python? - Stack Overflow
I would like to create a copy of an object. I want the new object to possess all properties of the old object (values of the fields). But I want to have independent objects. So, if I change values ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Use case of the .copy() method
I am trying to understand how shallow copies are useful, if any operation I perform on them will still be applied to the original list. That's incorrect, it won't. Have you tried actually using and playing around with .copy()? In [1]: list_a = [1, 2, 3] In [2]: list_reassign = list_a In [3]: list_shallow_copy = list_a.copy() In [4]: list_a, list_reassign, list_shallow_copy Out[4]: ([1, 2, 3], [1, 2, 3], [1, 2, 3]) In [5]: list_a.append(4) In [6]: list_a, list_reassign, list_shallow_copy Out[6]: ([1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3]) More on reddit.com
๐ŸŒ r/learnpython
23
3
June 12, 2024
python when to use copy.copy - Stack Overflow
I think I'm starting to understand python, but I still have trouble with a basic question. When to use copy.copy? >>>a=5 >>>b=a >>>a=6 >>>print b 5 Ok makes ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Why is copying a list so damn difficult in python?
This kind of confusion is mostly because you're thinking about python's object model wrong, or don't fully understand it. Perhaps this is a better way to think about things. Say you have this data structure: x = [ [1,2,3], [4,5,6], ] This statement creates 3 lists: 2 inner lists and one outer list. A reference to the outer list is then made available under the name x. When you execute this statement: y = x no data gets copied. You still have the same 3 lists in memory somewhere. All this did is make the outer list availible under the name y, in addition to its previous name x. When you execute this statement: y = list(x) or y = x[:] This creates a new list with the same contents as x. List x contained a reference to the 2 inner lists, so the new list will also contain a reference to those same 2 inner lists. Only one list is copiedโ€”the outer list. Now there are 4 lists in memory, the two inner lists, the outer list, and the copy of the outer list. The original outer list is available under the name x, and the new outer list is made available under the name y. The inner lists have not been copied! You can access and edit the inner lists from either x or y at this point! If you have a two dimensional (or higher) list, or any kind of nested data structure, and you want to make a full copy of everything, then you want to use the deepcopy() function in the copy module. Your solution also works for 2-D lists, as iterates over the items in the outer list and makes a copy of each of them, then builds a new outer list for all the inner copies. Hope this explanation helps. More on reddit.com
๐ŸŒ r/learnpython
30
9
March 16, 2013
๐ŸŒ
GitHub
github.com โ€บ python โ€บ cpython โ€บ blob โ€บ main โ€บ Lib โ€บ copy.py
cpython/Lib/copy.py at main ยท python/cpython
"""Shallow copy operation on arbitrary Python objects. ยท See the module's __doc__ string for more info. """ ยท cls = type(x) ยท if cls in _copy_atomic_types: return x ยท if cls in _copy_builtin_containers: return cls.copy(x) ยท
Author: python
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ copy-python-deep-copy-shallow-copy
Deep Copy and Shallow Copy in Python - GeeksforGeeks
In Python, assignment statements create references to the same object rather than copying it. Python provides the copy module to create actual copies which offer functions for shallow (copy.copy()) and deep (copy. deepcopy ()) copies.
Published: February 5, 2026
๐ŸŒ
Real Python
realpython.com โ€บ python-copy
How to Copy Objects in Python: Shallow vs Deep Copy Explained โ€“ Real Python
1 week ago - Custom classes can implement .__copy__() and .__deepcopy__() for specific copying behavior. Assignment in Python binds variable names to objects without copying, unlike some lower-level languages.
๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ ref_list_copy.asp
Python List copy() Method
Python Examples Python Compiler Python Exercises Python Quiz Python Challenges Python Practice Problems Python Server Python Syllabus Python Study Plan Python Interview Q&A Python Training ... The copy() method returns a copy of the specified list.
๐ŸŒ
Real Python
realpython.com โ€บ ref โ€บ stdlib โ€บ copy
copy | Python Standard Library โ€“ Real Python
The Python copy module provides functionality to create shallow copy and deep copies of objects in Python.
๐ŸŒ
Programiz
programiz.com โ€บ python-programming โ€บ shallow-deep-copy
Python Shallow Copy and Deep Copy (With Examples)
Essentially, sometimes you may want to have the original values unchanged and only modify the new values or vice versa. In Python, there are two ways to create copies:
Find elsewhere
Top answer
1 of 4
346

To get a fully independent copy of an object you can use the copy.deepcopy() function.

For more details about shallow and deep copying please refer to the other answers to this question and the nice explanation in this answer to a related question.

2 of 4
177

How can I create a copy of an object in Python?

So, if I change values of the fields of the new object, the old object should not be affected by that.

You mean a mutable object then.

In Python 3, lists get a copy method (in 2, you'd use a slice to make a copy):

>>> a_list = list('abc')
>>> a_copy_of_a_list = a_list.copy()
>>> a_copy_of_a_list is a_list
False
>>> a_copy_of_a_list == a_list
True

Shallow Copies

Shallow copies are just copies of the outermost container.

list.copy is a shallow copy:

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]

You don't get a copy of the interior objects. They're the same object - so when they're mutated, the change shows up in both containers.

Deep copies

Deep copies are recursive copies of each interior object.

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]

Changes are not reflected in the original, only in the copy.

Immutable objects

Immutable objects do not usually need to be copied. In fact, if you try to, Python will just give you the original object:

>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'copy'

Tuples don't even have a copy method, so let's try it with a slice:

>>> tuple_copy_attempt = a_tuple[:]

But we see it's the same object:

>>> tuple_copy_attempt is a_tuple
True

Similarly for strings:

>>> s = 'abc'
>>> s0 = s[:]
>>> s == s0
True
>>> s is s0
True

and for frozensets, even though they have a copy method:

>>> a_frozenset = frozenset('abc')
>>> frozenset_copy_attempt = a_frozenset.copy()
>>> frozenset_copy_attempt is a_frozenset
True

When to copy immutable objects

Immutable objects should be copied if you need a mutable interior object copied.

>>> tuple_of_list = [],
>>> copy_of_tuple_of_list = tuple_of_list[:]
>>> copy_of_tuple_of_list[0].append('a')
>>> copy_of_tuple_of_list
(['a'],)
>>> tuple_of_list
(['a'],)
>>> deepcopy_of_tuple_of_list = copy.deepcopy(tuple_of_list)
>>> deepcopy_of_tuple_of_list[0].append('b')
>>> deepcopy_of_tuple_of_list
(['a', 'b'],)
>>> tuple_of_list
(['a'],)

As we can see, when the interior object of the copy is mutated, the original does not change.

Custom Objects

Custom objects usually store data in a __dict__ attribute or in __slots__ (a tuple-like memory structure.)

To make a copyable object, define __copy__ (for shallow copies) and/or __deepcopy__ (for deep copies).

from copy import copy, deepcopy

class Copyable:
    __slots__ = 'a', '__dict__'
    def __init__(self, a, b):
        self.a, self.b = a, b
    def __copy__(self):
        return type(self)(self.a, self.b)
    def __deepcopy__(self, memo): # memo is a dict of id's to copies
        id_self = id(self)        # memoization avoids unnecesary recursion
        _copy = memo.get(id_self)
        if _copy is None:
            _copy = type(self)(
                deepcopy(self.a, memo), 
                deepcopy(self.b, memo))
            memo[id_self] = _copy 
        return _copy

Note that deepcopy keeps a memoization dictionary of id(original) (or identity numbers) to copies. To enjoy good behavior with recursive data structures, make sure you haven't already made a copy, and if you have, return that.

So let's make an object:

>>> c1 = Copyable(1, [2])

And copy makes a shallow copy:

>>> c2 = copy(c1)
>>> c1 is c2
False
>>> c2.b.append(3)
>>> c1.b
[2, 3]

And deepcopy now makes a deep copy:

>>> c3 = deepcopy(c1)
>>> c3.b.append(4)
>>> c1.b
[2, 3]
๐ŸŒ
Python
svn.python.org โ€บ projects โ€บ python โ€บ trunk โ€บ Lib โ€บ copy.py
copy.py
""" cls = type(x) copier = _copy_dispatch.get(cls) if copier: return copier(x) copier = getattr(cls, "__copy__", None) if copier: return copier(x) reductor = dispatch_table.get(cls) if reductor: rv = reductor(x) else: reductor = getattr(x, "__reduce_ex__", None) if reductor: rv = reductor(2) else: reductor = getattr(x, "__reduce__", None) if reductor: rv = reductor() else: raise Error("un(shallow)copyable object of type %s" % cls) return _reconstruct(x, rv, 0) _copy_dispatch = d = {} def _copy_immutable(x): return x for t in (type(None), int, long, float, bool, str, tuple, frozenset, type, xra
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ copy-module-python
Copy Module - Python - GeeksforGeeks
March 12, 2025 - copy module in Python provides essential functions for duplicating objects. It allows developers to create both shallow and deep copies of objects ensuring that modifications to the copy do not inadvertently affect the original object (or vice ...
๐ŸŒ
Python Module of the Week
pymotw.com โ€บ 2 โ€บ copy
copy โ€“ Duplicate objects - Python Module of the Week
Now available for Python 3! Buy the book! ... The copy module includes 2 functions, copy() and deepcopy(), for duplicating existing objects.
๐ŸŒ
Scaler
scaler.com โ€บ home โ€บ topics โ€บ copy in python
Copy in Python - Scaler Topics
May 8, 2024 - In this point class, we created a Point object with two variables, a and b. And we have created a __repr__ function for ease of access to the values of the objects. Now we're going to see how the copy() functions work on objects that we have created. ... In this case, our Point class uses immutable data types in python - the int and hence here, a shallow copy or a deep copy is the same.
๐ŸŒ
Python for the Lab
pythonforthelab.com โ€บ blog โ€บ deep-and-shallow-copies-of-objects
Deep and Shallow Copies of Objects | Python For The Lab
It is very important to point out that, if are worried about copying and deep copying of custom objects, you should understand what are mutable and immutable objects in Python, and what are hashable objects. When you have immutable data types, such as an integer or a string, all the discussion above doesn't work.
๐ŸŒ
Note.nkmk.me
note.nkmk.me โ€บ home โ€บ python
Shallow and Deep Copy in Python: copy(), deepcopy() | note.nkmk.me
May 13, 2023 - Difference between the == and is operators in Python ยท To create a copy instead of a reference of the same object, use the copy() method or the copy.copy() and copy.deepcopy() functions described below.
๐ŸŒ
AskPython
askpython.com โ€บ python-modules โ€บ python-copy
Python Copy - Perform Deep and Shallow Copy - AskPython
August 6, 2022 - However, due to copying all objects, this deepcopy method is a bit more expensive, as compared to the shallow copy method. So use this wisely, only when you need it! In this article, we learned about using the Python Copy module, to perform shallow copy and deep copy operations.
๐ŸŒ
freeCodeCamp
freecodecamp.org โ€บ news โ€บ how-to-copy-objects-in-python
How to Copy Objects in Python
April 17, 2025 - Modules: importing and using them in the program. Basic understanding of methods and functions. ... The copy module is an in-built module in Python which is primarily used for copying objects in Python.
Top answer
1 of 2
34

Basically, b = a points b to wherever a points, and nothing else.

What you're asking about is mutable types. Numbers, strings, tuples, frozensets, booleans, None, are immutable. Lists, dictionaries, sets, bytearrays, are mutable.

If I make a mutable type, like a list:

>>> a = [1, 2]  # create an object in memory that points to 1 and 2, and point a at it
>>> b = a       # point b to wherever a points
>>> a[0] = 2    # change the object that a points to by pointing its first item at 2
>>> a
[2, 2]
>>> b
[2, 2]

They'll both still point to the same item.

I'll comment on your original code too:

>>>a=5     # '5' is interned, so it already exists, point a at it in memory
>>>b=a     # point b to wherever a points
>>>a=6     # '6' already exists in memory, point a at it
>>>print b # b still points at 5 because you never moved it
5

You can always see where something points to in memory by doing id(something).

>>> id(5)
77519368
>>> a = 5
>>> id(a)
77519368     # the same as what id(5) showed us, 5 is interned
>>> b = a
>>> id(b)
77519368     # same again
>>> id(6)
77519356
>>> a = 6
>>> id(a)
77519356     # same as what id(6) showed us, 6 is interned
>>> id(b)
77519368     # still pointing at 5.    
>>> b
5

You use copy when you want to make a copy of a structure. However, it still will not make a copy of something that is interned. This includes integers less than 256, True, False, None, short strings like a. Basically, you should almost never use it unless you're sure you won't be messed up by interning.

Consider one more example, that shows even with mutable types, pointing one variable at something new still doesn't change the old variable:

>>> a = [1, 2]
>>> b = a
>>> a = a[:1]    # copy the list a points to, starting with item 2, and point a at it
>>> b            # b still points to the original list
[1, 2]
>>> a
[1]
>>> id(b)
79367984
>>> id(a)
80533904

Slicing a list (whenever you use a :) makes a copy.

2 of 2
4

Assignment never copies. It just links the object the a references (to stick to the example) to b. a and b reference the same object until you change the link of one.

It's useful to drop "variable" as a term, it's just a label you put on an object, a handle you can use to get through to the object, nothing more.

copy.copy doesn't change this at all.

If you want to propagate changes even for numbers or strings - here does the immutability show - you have to wrap the numbers and strings in a another object and assign it to a and b.

If you want to go the other way round you have to use the copy module, but make sure to read the docs. But you have to think in term of objects not variables.

๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ python_lists_copy.asp
Python - Copy Lists
Python Examples Python Compiler Python Exercises Python Quiz Python Challenges Python Practice Problems Python Server Python Syllabus Python Study Plan Python Interview Q&A Python Training ... You cannot copy a list simply by typing list2 = list1, because: list2 will only be a reference to list1, and changes made in list1 will automatically also be made in list2.