What are the options to clone or copy a list in Python?
new_list = my_list then modifies
new_list every time
Why is this?
To actually copy the list, you have various possibilities:
Felix already provided an excellent answer, but I thought I'd do a speed comparison of the various methods:
So the fastest is list slicing. But be aware that
(Here's the script if anyone's interested or wants to raise any issues:)
EDIT: Added new-style, old-style classes and dicts to the benchmarks, and made the python version much faster and added some more methods including list expressions and
In Python 3, a shallow copy can be made with:
In Python 2 and 3, you can get a shallow copy with a full slice of the original:
There are two semantic ways to copy a list. A shallow copy creates a new list of the same objects, a deep copy creates a new list containing new equivalent objects.
Shallow list copy
A shallow copy only copies the list itself, which is a container of references to the objects in the list. If the objects contained themselves are mutable and one is changed, the change will be reflected in both lists.
There are different ways to do this in Python 2 and 3. The Python 2 ways will also work in Python 3.
In Python 2, the idiomatic way of making a shallow copy of a list is with a complete slice of the original:
You can also accomplish the same thing by passing the list through the list constructor,
but using the constructor is less efficient:
In Python 3, lists get the
In Python 3.5:
Making another pointer does not make a copy
The list is just an array of pointers to the contents, so a shallow copy just copies the pointers, and so you have two different lists, but they have the same contents. To make copies of the contents, you need a deep copy.
To demonstrate how this allows us to make new sub-lists:
And so we see that the deep copied list is an entirely different list from the original. You could roll your own function - but don't. You're likely to create bugs you otherwise wouldn't have by using the standard library's deepcopy function.
There are many answers already that tell you how to make a proper copy, but none of them say why your original 'copy' failed.
Python doesn't store values in variables; it binds names to objects. Your original assignment took the object referred to by
Each element of a list acts like a name, in that each element binds non-exclusively to an object. A shallow copy creates a new list whose elements bind to the same objects as before.
To take your list copy one step further, copy each object that your list refers to, and bind those element copies to a new list.
This is not yet a deep copy, because each element of a list may refer to other objects, just like the list is bound to its elements. To recursively copy every element in the list, and then each other object referred to by each element, and so on: perform a deep copy.
See the documentation for more information about corner cases in copying.
All of the other contributors gave great answers, which work when you have a single dimension (leveled) list, however of the methods mentioned so far, only
Edit: New information brought to light
As others have stated, there
Basically what this does is make a representation of
If you then check the contents of each list, for example a 4 by 3 list, Python will return
While this probably isn't the canonical or syntactically correct way to do it, it seems to work well. I haven't tested performance, but I am going to guess that
Unlike other languages have variable and value, python has name and object.
means give the list(object) a name "a", the
just gives the same object a new name "b", so whenever you do something with a, the object changes and therefore b changes.
The only way to make a really copy of a is to create a new object like other answers have said.
You can see more about this here
Python 3.6.0 Timings
Here are the timing results using Python 3.6.0. Keep in mind these times are relative to one another, not absolute.
We can see the old winner still comes out on top, but not really by a huge amount, considering the increased readability of the Python3
Note that these methods do not output equivalent results for any input other than lists. They all work for sliceable objects, a few work for any iterable, but only
Here is the testing code for interested parties (Template from here):
Now if you assign
The Other way you can do this are :
Not sure if this is still actual, but the same behavior holds for dictionaries as well. Look at this example.
A very simple approach independent of python version was missing in already given answers which you can use most of the time (at least I do):
However, If my_list contains other containers (for eg. nested lists) you must use deepcopy as others suggested in the answers above from the copy library. For example:
.Bonus: If you don't want to copy elements use (aka shallow copy):
Let's understand difference between Solution#1 and Solution #2
As you can see Solution #1 worked perfectly when we were not using the nested lists. Let's check what will happen when we apply solution #1 to nested lists.
So Suppose you have two list :
And we have to copy both list , now starting from the first list:
So first let's try by general method of copy:
Now if you are thinking copy copied the list_1 then you can be wrong, let's check it:
Surprised ? Ok let's explore it:
So as we know python doesn't store anything in a variable, Variables are just referencing to the object and object store the value. Here object is
so when you do
Here in the image list_1 and copy are two variable names but the object is same for both variable which is
So if you try to modify copied list then it will modify the original list too because the list is only one there, you will modify that list no matter you do from the copied list or from the original list:
So it modified the original list :
Now let's move to a second pythonic method of copying list:
Now this method fix the thing what we were facing in first issue let's check it :
So as we can see our both list having different id and it means both variables are pointing to different objects so what actually going on here is :
Now let's try to modify the list and let's see if we still face the previous problem :
So as you can see it is not modifying the original list, it only modified the copied list, So we are ok with it.
So now i think we are done? wait we have to copy the second nested list too so let's try pythonic way :
So list_2 should reference to another object which is copy of list_2 let's check:
we get the output:
Now we can assume both lists are pointing different object so now let's try to modify it and let's see it is giving what we want :
So when we try:
it gives us output:
Now, this is little confusing we used the pythonic way and still, we are facing the same issue.
let's understand it:
So when we do :
we are actually copying the outer list only, not the nested list, so nested list is same object for both list, let's check:
So actually when we do
It creates the copy of list but only outer list copy, not the nested list copy, nested list is same for both variable so if you try to modify the nested list then it will modify the original list too because nested list object is same for both nested list.
So what is the solution?
So now let's check it :
both id are different , now let's check nested list id:
As you can see both id are different so we can assume that both nested list are pointing different object now.
So when you do
So both nested list are pointing different object and they have seprate copy of nested list now.
Now let's try to modify the nested list and let's see if it solved the previous issue or not:
so if we do :
So as you can see it didn't modify the original nested list , it only modified the copied list.
If you like my detailed answer , let me know by upvoting it , if you have any doubt realted this answer , comment down :)
you can use bulit in list() function:
i think this code will help you.