new_list = my_list doesn't actually create a second list. The assignment just copies the reference to the list, not the actual list, so both new_list and my_list refer to the same list after the assignment.

To actually copy the list, you have several options:

  • You can use the built-in list.copy() method (available since Python 3.3):

    new_list = old_list.copy()
    
  • You can slice it:

    new_list = old_list[:]
    

    Alex Martelli's opinion (at least back in 2007) about this is, that it is a weird syntax and it does not make sense to use it ever. ;) (In his opinion, the next one is more readable).

  • You can use the built-in list() constructor:

    new_list = list(old_list)
    
  • You can use generic copy.copy():

    import copy
    new_list = copy.copy(old_list)
    

    This is a little slower than list() because it has to find out the datatype of old_list first.

  • If you need to copy the elements of the list as well, use generic copy.deepcopy():

    import copy
    new_list = copy.deepcopy(old_list)
    

    Obviously the slowest and most memory-needing method, but sometimes unavoidable. This operates recursively; it will handle any number of levels of nested lists (or other containers).

Example:

import copy

class Foo(object):
    def __init__(self, val):
         self.val = val

    def __repr__(self):
        return f'Foo({self.val!r})'

foo = Foo(1)

a = ['foo', foo]
b = a.copy()
c = a[:]
d = list(a)
e = copy.copy(a)
f = copy.deepcopy(a)

# edit orignal list and instance 
a.append('baz')
foo.val = 5

print(f'original: {a}\nlist.copy(): {b}\nslice: {c}\nlist(): {d}\ncopy: {e}\ndeepcopy: {f}')

Result:

original: ['foo', Foo(5), 'baz']
list.copy(): ['foo', Foo(5)]
slice: ['foo', Foo(5)]
list(): ['foo', Foo(5)]
copy: ['foo', Foo(5)]
deepcopy: ['foo', Foo(1)]
Answer from Felix Kling on Stack Overflow
๐ŸŒ
Programiz
programiz.com โ€บ python-programming โ€บ methods โ€บ list โ€บ copy
Python list copy (with Code Visualization)
The copy() method returns a shallow copy of the list. In this tutorial, we will learn about the Python List copy() method with the help of examples.
Top answer
1 of 1
4159

new_list = my_list doesn't actually create a second list. The assignment just copies the reference to the list, not the actual list, so both new_list and my_list refer to the same list after the assignment.

To actually copy the list, you have several options:

  • You can use the built-in list.copy() method (available since Python 3.3):

    new_list = old_list.copy()
    
  • You can slice it:

    new_list = old_list[:]
    

    Alex Martelli's opinion (at least back in 2007) about this is, that it is a weird syntax and it does not make sense to use it ever. ;) (In his opinion, the next one is more readable).

  • You can use the built-in list() constructor:

    new_list = list(old_list)
    
  • You can use generic copy.copy():

    import copy
    new_list = copy.copy(old_list)
    

    This is a little slower than list() because it has to find out the datatype of old_list first.

  • If you need to copy the elements of the list as well, use generic copy.deepcopy():

    import copy
    new_list = copy.deepcopy(old_list)
    

    Obviously the slowest and most memory-needing method, but sometimes unavoidable. This operates recursively; it will handle any number of levels of nested lists (or other containers).

Example:

import copy

class Foo(object):
    def __init__(self, val):
         self.val = val

    def __repr__(self):
        return f'Foo({self.val!r})'

foo = Foo(1)

a = ['foo', foo]
b = a.copy()
c = a[:]
d = list(a)
e = copy.copy(a)
f = copy.deepcopy(a)

# edit orignal list and instance 
a.append('baz')
foo.val = 5

print(f'original: {a}\nlist.copy(): {b}\nslice: {c}\nlist(): {d}\ncopy: {e}\ndeepcopy: {f}')

Result:

original: ['foo', Foo(5), 'baz']
list.copy(): ['foo', Foo(5)]
slice: ['foo', Foo(5)]
list(): ['foo', Foo(5)]
copy: ['foo', Foo(5)]
deepcopy: ['foo', Foo(1)]
๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ ref_list_copy.asp
Python List copy() Method
Remove List Duplicates Reverse ... Python Study Plan Python Interview Q&A Python Training ... The copy() method returns a copy of the specified list....
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ copy.html
copy โ€” Shallow and deep copy operations
Shallow copies of many collections can be made using the corresponding copy() method (such as list.copy(), dict.copy() or set.copy()), and of sequences (such as lists or bytearrays) by making a slice of the entire sequence (sequence[:]).
๐ŸŒ
Tutorialspoint
tutorialspoint.com โ€บ python โ€บ python_copy_lists.htm
Python - Copy Lists
We can copy a list using the copy() function by invoking it on the original list. This creates a new list object that contains the same elements as the original list. In the following example, we are using the copy() function to creates a new ...
Find elsewhere
๐ŸŒ
w3resource
w3resource.com โ€บ python โ€บ list โ€บ list_copy.php
Python List copy() Method
June 5, 2024 - Python List - copy() Method: The copy() method returns a copy of a given list.
๐ŸŒ
DataCamp
datacamp.com โ€บ tutorial โ€บ python-copy-list
Python Copy List: What You Should Know | DataCamp
August 13, 2024 - These changes occur since the two lists are stored in the same memory. Now, letโ€™s take a look at the different ways to actually copy our list. The copy() method is a built-in method used to create a shallow copy of the list.
๐ŸŒ
Toppr
toppr.com โ€บ guides โ€บ python-guide โ€บ references โ€บ methods-and-functions โ€บ python-list-copy
Python Copy List: How to copy a list in python, Examples
July 1, 2024 - This creates a shallow list, meaning ... copy a list without references by using the copy(). The copy() generates a shallow list that does not include the references....
๐ŸŒ
SitePoint
sitepoint.com โ€บ python hub โ€บ copy lists
Python - Copy Lists | SitePoint โ€” SitePoint
This is equivalent to the copy() method. ... The slice [:] creates a new list by copying all elements of original_list.
๐ŸŒ
Career Karma
careerkarma.com โ€บ blog โ€บ python โ€บ how to copy a list in python
How to Copy a List in Python: A Complete Guide | Career Karma
December 1, 2023 - The new list refers to the same object as the old list. The Python copy() method creates a copy of an existing list. The copy() method is added to the end of a list object and so it does not accept any parameters.
Top answer
1 of 10
416

E0_copy is not a deep copy. You don't make a deep copy using list(). (Both list(...) and testList[:] are shallow copies, as well as testList.copy().)

You use copy.deepcopy(...) for deep copying a list.

copy.deepcopy(x[, memo])

Return a deep copy of x.

See the following snippet -

>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b   # b changes too -> Not a deepcopy.
[[1, 10, 3], [4, 5, 6]]

Now see the deepcopy operation

>>> import copy
>>> b = copy.deepcopy(a)
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 10, 3], [4, 5, 6]]
>>> a[0][1] = 9
>>> a
[[1, 9, 3], [4, 5, 6]]
>>> b    # b doesn't change -> Deep Copy
[[1, 10, 3], [4, 5, 6]]

To explain, list(...) does not recursively make copies of the inner objects. It only makes a copy of the outermost list, while still referencing the same inner lists, hence, when you mutate the inner lists, the change is reflected in both the original list and the shallow copy. You can see that shallow copying references the inner lists by checking that id(a[0]) == id(b[0]) where b = list(a).

2 of 10
104

In Python, there is a module called copy with two useful functions:

import copy
copy.copy()
copy.deepcopy()

copy() is a shallow copy function. If the given argument is a compound data structure, for instance a list, then Python will create another object of the same type (in this case, a new list) but for everything inside the old list, only their reference is copied. Think of it like:

newList = [elem for elem in oldlist]

Intuitively, we could assume that deepcopy() would follow the same paradigm, and the only difference is that for each elem we will recursively call deepcopy, (just like mbguy's answer)

but this is wrong!

deepcopy() actually preserves the graphical structure of the original compound data:

a = [1,2]
b = [a,a] # there's only 1 object a
c = deepcopy(b)

# check the result
c[0] is a # False, a new object a_1 is created
c[0] is c[1] # True, c is [a_1, a_1] not [a_1, a_2]

This is the tricky part: during the process of deepcopy(), a hashtable (dictionary in Python) is used to map each old object ref onto each new object ref, which prevents unnecessary duplicates and thus preserves the structure of the copied compound data.

Official docs

๐ŸŒ
AskPython
askpython.com โ€บ python โ€บ list โ€บ copy-a-list-in-python
Ways to Copy a List in Python - AskPython
August 6, 2022 - Python slicing operator is considered to be the most efficient way to copy elements of a Python list.
๐ŸŒ
Sentry
sentry.io โ€บ sentry answers โ€บ python โ€บ clone a list in python
Clone a List in Python With Shallow and Deep Copy | Sentry
1 week ago - Create independent copies of Python lists using list.copy, slicing, the list constructor for shallow copies, or copy.deepcopy for nested structures
๐ŸŒ
Reddit
reddit.com โ€บ r/askprogramming โ€บ why choose to copy a list with slices instead of copy(), deepcopy(), or list()??
r/AskProgramming on Reddit: Why choose to copy a list with slices instead of copy(), deepcopy(), or list()??
November 3, 2022 -

Hi there! beginner Python programmer here~

I've been thinking more and more about what Python is doing in the background because I've noticed that it improves the way I think of writing programs. And because I had to copy a list in one of my school assignments, I got curious about what the best way to go about it is.

I looked it up and got a bunch of articles explaining about copy() and deepcopy() in detail, explaining how deepcopy is used when dealing with lists with mutable elements, etc. So, I guess I understand what those two are doing to an extent.

However, when it comes to copying a list with slicing (cloning) or by using list(), all I've been able to find is that cloning is much faster because it just copies a piece of memory onto a new location, and with list() the function needs to be called first. That I understand. But when would I want to use the one method over the other? Or when would I rather use list() instead of copy()?? does list() copy shallow or deep??? would I only want to use cloning when my goal is speed? does one use up more memory than the other? Those are questions that pop into my head.

And it doesn't stop there because I found this one article ( Python | Cloning or Copying a list - GeeksforGeeks ) that explains FIVE other ways to copy a list... Does Python just have multiple ways to copy a list in the same way??? or is it because Python language updates that caused there to be overlap?? Or does every technique have a specific purpose/result, even if the difference might be slight??

I have also found a few articles that might have discussed this in greater detail, but they were just too complicated for me to understand. I have only been doing this for a few weeks

Top answer
1 of 3
3
Does Python just have multiple ways to copy a list in the same way??? Although most of the approaches mentioned can be used to copy lists, that doesn't mean that's what they're for! Every operation has a different purpose: Using the slicing technique The purpose of slicing is to select an arbitrary subset of a list. Slices can be used to either obtain a copy of this subset, or to modify the selected subset. For example: foo = [1, 2, 3, 4, 5] print(foo[1:3]) # will print: [2, 3] foo[1:3] = ['a', 'b', 'c', 'd'] print(foo) # will print: [1, a, b, c, d, 4, 5] 2. Using the extend() method The purpose of extend is to add a whole other collection of items onto the end of an existing list. Although slicing can be used for this too, .extend() is less error prone since you don't have to worry about calculating the correct indexes. 3. List copy using =(assignment operator) Geeksforgeeks is wrong here. The = operator doesn't make a copy. Rather, you simply have two different variables refer to the exact same list. 4. Using the method of Shallow Copy Python's copy module wasn't made for lists. The copy() and deepcopy() functions are able to make copies of any arbitrary Python object. For example: from copy import copy class Person: def __init__(self, fname, lname): self.first_name = fname self.last_name = lname def print_greeting(self): print(f"Hello! My name is {self.first_name} {self.last_name}.") foo = Person("Jack", "Johnson") foo.print_greeting() # Will print: Hello! My name is Jack Johnson. bar = copy(foo) bar.print_greeting() # Will print: Hello! My name is Jack Johnson. foo.first_name = "John" foo.last_name = "Jackson" foo.print_greeting() # Will print: Hello! My name is John Jackson bar.print_greeting() # Will print: Hello! My name is Jack Johnson As you see, the copy operation actually made a copy of our Person object. The fact that it works for lists is just a consequence, but that doesn't make it the way of copying lists. 5. Using list comprehension List comprehensions are for constructing a new list based on the data in existing collections. Basically, they're meant to be a concise way to compose map() and filter() operations. You can also use it to quickly construct the cartesian product of multiple collections. 6. Using the append() method The append operation is simply for adding a single item onto a list. Nothing more. Manually writing your own for-loop to append items one by one is perhaps the most clucky & verbose way to copy a list. 7. Using the copy() method This is the only operation whose specific purpose is to copy a Python list. It's finely tuned just for that. Thus, it'll offer you the best performance. 8. Using the method of Deep Copy See #4. The deepcopy() function can make a copy of any arbitrary object, not just a list. 9. The list() function (not mentioned on geeksforgeeks). This is simply the list class constructor. Since 'list' is a class, it has to have a constructor, so might as well make it useful. It can accept any arbitrary collection - a set, a dictionary, a generator, a custom collection class, basically any object that has __iter__ defined on it. It uses the iterator interface to copy each item one by one into the new Python list.
2 of 3
2
I've always assumed that [:] making a full copy was a "happy accident". They made it so that omitting the first argument results in the start defaulting to the start of the list, and omitting the second argument results in the end defaulting to the end of the list. The consequence then of omitting both is that the entire list is copied. And I posted this in another comment, but do not use G4G. Their "articles" contain a lot of misinformation; as is the case here. The section on = is nonsense. They seemed to have tried to "correct" it by writing Note: There is an issue with this method if you modify in the new list then the old list is also modified due to the new list is referencing But that just shows that they don't understand what "copy" even means.
๐ŸŒ
Educative
educative.io โ€บ answers โ€บ how-to-copy-a-list-in-python
How to copy a list in Python
If you need a shallow copy of a list, the built-in copy() function can be used.