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
๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ python_lists_copy.asp
Python - Copy Lists
You can use the built-in List method copy() to copy a list.
๐ŸŒ
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 16
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)]
2 of 16
775

Felix already provided an excellent answer, but I thought I'd do a speed comparison of the various methods:

  1. 10.59 sec (105.9 ยตs/itn) - copy.deepcopy(old_list)
  2. 10.16 sec (101.6 ยตs/itn) - pure Python Copy() method copying classes with deepcopy
  3. 1.488 sec (14.88 ยตs/itn) - pure Python Copy() method not copying classes (only dicts/lists/tuples)
  4. 0.325 sec (3.25 ยตs/itn) - for item in old_list: new_list.append(item)
  5. 0.217 sec (2.17 ยตs/itn) - [i for i in old_list] (a list comprehension)
  6. 0.186 sec (1.86 ยตs/itn) - copy.copy(old_list)
  7. 0.075 sec (0.75 ยตs/itn) - list(old_list)
  8. 0.053 sec (0.53 ยตs/itn) - new_list = []; new_list.extend(old_list)
  9. 0.039 sec (0.39 ยตs/itn) - old_list[:] (list slicing)

So the fastest is list slicing. But be aware that copy.copy(), list[:] and list(list), unlike copy.deepcopy() and the python version don't copy any lists, dictionaries and class instances in the list, so if the originals change, they will change in the copied list too and vice versa.

(Here's the script if anyone's interested or wants to raise any issues:)

from copy import deepcopy

class old_class:
    def __init__(self):
        self.blah = 'blah'

class new_class(object):
    def __init__(self):
        self.blah = 'blah'

dignore = {str: None, unicode: None, int: None, type(None): None}

def Copy(obj, use_deepcopy=True):
    t = type(obj)

    if t in (list, tuple):
        if t == tuple:
            # Convert to a list if a tuple to
            # allow assigning to when copying
            is_tuple = True
            obj = list(obj)
        else:
            # Otherwise just do a quick slice copy
            obj = obj[:]
            is_tuple = False

        # Copy each item recursively
        for x in xrange(len(obj)):
            if type(obj[x]) in dignore:
                continue
            obj[x] = Copy(obj[x], use_deepcopy)

        if is_tuple:
            # Convert back into a tuple again
            obj = tuple(obj)

    elif t == dict:
        # Use the fast shallow dict copy() method and copy any
        # values which aren't immutable (like lists, dicts etc)
        obj = obj.copy()
        for k in obj:
            if type(obj[k]) in dignore:
                continue
            obj[k] = Copy(obj[k], use_deepcopy)

    elif t in dignore:
        # Numeric or string/unicode?
        # It's immutable, so ignore it!
        pass

    elif use_deepcopy:
        obj = deepcopy(obj)
    return obj

if __name__ == '__main__':
    import copy
    from time import time

    num_times = 100000
    L = [None, 'blah', 1, 543.4532,
         ['foo'], ('bar',), {'blah': 'blah'},
         old_class(), new_class()]

    t = time()
    for i in xrange(num_times):
        Copy(L)
    print 'Custom Copy:', time()-t

    t = time()
    for i in xrange(num_times):
        Copy(L, use_deepcopy=False)
    print 'Custom Copy Only Copying Lists/Tuples/Dicts (no classes):', time()-t

    t = time()
    for i in xrange(num_times):
        copy.copy(L)
    print 'copy.copy:', time()-t

    t = time()
    for i in xrange(num_times):
        copy.deepcopy(L)
    print 'copy.deepcopy:', time()-t

    t = time()
    for i in xrange(num_times):
        L[:]
    print 'list slicing [:]:', time()-t

    t = time()
    for i in xrange(num_times):
        list(L)
    print 'list(L):', time()-t

    t = time()
    for i in xrange(num_times):
        [i for i in L]
    print 'list expression(L):', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        a.extend(L)
    print 'list extend:', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        for y in L:
            a.append(y)
    print 'list append:', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        a.extend(i for i in L)
    print 'generator expression extend:', time()-t
๐ŸŒ
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
Copying a list in Python refers to creating a new list that contains the same elements as the original list. There are different methods for copying a list, including, using slice notation, the list() function, and using the copy() method.
๐ŸŒ
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.
Find elsewhere
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

๐ŸŒ
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 - The copy() does not take any parameters as input from the users. A shallow list will be returned as output after using the copy().
๐ŸŒ
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.
๐ŸŒ
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.
๐ŸŒ
Microsoft Learn
learn.microsoft.com โ€บ en-us โ€บ dotnet โ€บ api โ€บ system.collections.generic.list-1.copyto
List<T>.CopyTo Method (System.Collections.Generic) | Microsoft Learn
Public Sub CopyTo (index As Integer, array As T(), arrayIndex As Integer, count As Integer) ... The zero-based index in the source List<T> at which copying begins.
๐ŸŒ
Codecademy
codecademy.com โ€บ docs โ€บ python โ€บ lists โ€บ .copy()
Python | Lists | .copy() | Codecademy
October 13, 2023 - If you want the original list unchanged when the new list is modified, you can use the .copy() method.
๐ŸŒ
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.
๐ŸŒ
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
๐ŸŒ
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.
๐ŸŒ
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.