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
Remove List Duplicates Reverse a String Add Two Numbers · 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.
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
Discussions

How to properly copy a list of dictionaries in python?
I’ve been having trouble with a script and I isolated the issue to the fact that my for loops are somehow modifying an unrelated list (as far as I can tell). I replicated the result with this piece of code: list1 = [{"k… More on forum.inductiveautomation.com
🌐 forum.inductiveautomation.com
5
0
December 29, 2021
I just found out I've been copying lists wrong all along.
You should do some_numbers = other_numbers.copy() To get a fresh instance of the list. More on reddit.com
🌐 r/learnpython
148
677
September 17, 2020
How may I copy a list of list without reference?
I can copy a list without reference a = [3,4,5] b = a.copy() b[0] = -1 print(a) print(b) >>[3, 4, 5] >>[-1, 4, 5] but why can’t I do the same for a list of list? What should I do? a = [[1,1],[1,1]] b = a.copy() b[0][0] = -1 print(a) print(b) >>[[-1, 1], [1, 1]] >>[[-1, 1], [1, 1]] More on discuss.python.org
🌐 discuss.python.org
2
0
October 20, 2023
Why choose to copy a list with slices instead of copy(), deepcopy(), or list()??
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. More on reddit.com
🌐 r/AskProgramming
11
1
November 3, 2022
🌐
SitePoint
sitepoint.com › python hub › copy lists
Python - Copy Lists | SitePoint — SitePoint
We’ll cover both shallow and deep copying techniques. In Python, lists are mutable objects, meaning their contents can be altered after creation. When you assign a list to another variable using the = operator, you don’t create a new copy of the list—you simply create a new reference to the same object in memory.
🌐
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[:]).
🌐
Digitalis
digitalis.io › post › return-to-basics-python-list-append-extend-copy-deepcopy-and-assignment
Return To Basics: Python List, Append, Extend, Copy, Deepcopy, and Assignment | Digitalis Blog
February 20, 2026 - It is more efficient than doing a loop yourself in Python. When you want to merge another list (or tuple, etc.) into your list, flattened. copy() makes a new list object, but its contents are still references to the original elements.
Find elsewhere
🌐
Programiz
programiz.com › python-programming › methods › list › copy
Python list copy (with Code Visualization)
Online Python Online JavaScript Online SQL Online Java Online HTML Online C Online C++ Online C# Online PHP Online Swift Online Kotlin Online TypeScript Online Go Online Rust Online Scala Online Dart Online R Online Ruby ... The copy() method returns a shallow copy of the list.
🌐
Inductive Automation
forum.inductiveautomation.com › ignition
How to properly copy a list of dictionaries in python? - Ignition - Inductive Automation Forum
December 29, 2021 - I’ve been having trouble with a script and I isolated the issue to the fact that my for loops are somehow modifying an unrelated list (as far as I can tell). I replicated the result with this piece of code: list1 = [{"key1": 1, "key2": 2}] list2 = list(list1) print "ID of list1: " + str(id(list1)) print "ID of list2: " + str(id(list2)) print "Contents of list1: " + str(list1) print "Contents of list2: " + str(list2) list2[0]["key1"] = 999 print "ID of list1: " + str(id(list1)) print "ID o...
🌐
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.
🌐
Python Engineer
python-engineer.com › posts › how-to-copy-list
How to copy a List in Python without side effects - Python Engineer
January 12, 2023 - When we simply use the copy assignment we only copy the reference to the List: ... Both objects point to the same memory location, so changing one List also affects the other one!
🌐
Reddit
reddit.com › r/learnpython › i just found out i've been copying lists wrong all along.
r/learnpython on Reddit: I just found out I've been copying lists wrong all along.
September 17, 2020 -

In order to explain this, assume we have two lists: some_numbers and other_numbers, where

>>> some_numbers = [1, 2, 3, 4, 5]
>>> other_numbers = some_numbers

Many beginners would make a copy of some_numbers and store it in other_numbers, as I did above. However, what you might not know, is that when you do that you actually tell Python that they are the same list. So if you tried to add an item to some_numbers and then print(other_numbers), you'd see that the output will include the item you added to some_numbers. i.e.:

>>> some_numbers.append(10)
>>> print(other_numbers)
[1, 2, 3, 4, 5, 10]

If you wish to have two independent lists, where adding an item to one doesn't change the other, use this instead:

>>> some_numbers = [1, 2, 3, 4, 5]
>>> other_numbers = some_numbers[:]

Now, you can change the lists independently.

>>> some_numbers.append(10)
>>> other_numbers.append(20)
>>> print(some_numbers)
>>> print(other_numbers)
[1, 2, 3, 4, 5, 10]
[1, 2, 3, 4, 5, 20]

Edit: As mentioned in the comments by several people, the more readable option for copying is

>>> some_numbers = [ 1, 2, 3, 4, 5]
>>> other_numbers = some_numbers.copy()

🌐
Sentry
sentry.io › sentry answers › python › clone a list in python
Clone a List in Python With Shallow and Deep Copy | Sentry
November 15, 2023 - Create independent copies of Python lists using list.copy, slicing, the list constructor for shallow copies, or copy.deepcopy for nested structures
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-cloning-copying-list
Cloning or Copying a List - Python - GeeksforGeeks
copy() method is a built-in method in Python that creates a shallow copy of a list.
Published: October 28, 2025
🌐
Python.org
discuss.python.org › python help
How may I copy a list of list without reference? - Python Help - Discussions on Python.org
October 20, 2023 - I can copy a list without reference a = [3,4,5] b = a.copy() b[0] = -1 print(a) print(b) >>[3, 4, 5] >>[-1, 4, 5] but why can’t I do the same for a list of list? What should I do? a = [[1,1],[1,1]] b = a.copy() b[0][0] = -1 print(a) print(b) >>[[-1, 1], [1, 1]] >>[[-1, 1], [1, 1]]
🌐
DataCamp
datacamp.com › tutorial › python-copy-list
Python Copy List: What You Should Know | DataCamp
August 13, 2024 - ... The example below shows how to copy a list in Python using the copy() method. Notice how the original list remains unchanged even though changes are made to the duplicate list.
🌐
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.
🌐
All About AI-ML
indhumathychelliah.com › 2021 › 08 › 31 › 5-different-ways-to-copy-list-in-python
5 Different Ways to Copy List in Python – All About AI-ML
January 2, 2022 - Copying Python List Photo by Julia Filirovska from Pexels In this article, I have covered different ways to copy lists in python. 1. Assignment Operation We can copy the list using assignment operation = copied_list=original_list Both original_list and copied_list will point to the same list object. https://gist.github.com/IndhumathyChelliah/b55c82c8f02a19f9e9fa93877044e257 Modifications done in original_list will be reflected in copied_list and…
🌐
Python.org
discuss.python.org › python help
List.copy() bug when using list of lists (Solved) - Python Help - Discussions on Python.org
December 6, 2022 - I’m new to Python and was driven crazy by this “feature” or bug. Run the program below and could someone please explain the behaviour. If you read the documentation for copy() it clearly states a shadow copy of a list is created and returned. I am using 3.11.0 and IDLE and for a list of simple elements copy() works as expected.
🌐
Reddit
reddit.com › r/learnpython › why is making a copy of a list is preferred sometimes?
r/learnpython on Reddit: Why is making a copy of a list is preferred sometimes?
December 25, 2021 -

Hi, I'm a Python beginner and my preferred path is Data Science if this has anything to do with the question.

I've noticed in tutorials, that they sometimes copy a particular list that needs to be manipulated. Sometimes even when there's no obvious reason for that list to be copied, or when that original list won't be used again in the code.

Is this practice only with lists or with other types of variables as well? And why do we copy a list rather just manipulating the original one?

🌐
Vultr Docs
docs.vultr.com › python › standard-library › list › copy
Python list copy() - Duplicate List | Vultr Docs
November 7, 2024 - Define a list of simple elements like integers or strings. Use the copy() method to make a duplicate of the list.