Question and Answer

how to copy a list in python

Let’s start from the beginning and explore this question.

So let’s suppose you have two lists:

list_1=['01','98']
list_2=[['01','98']]

And we have to copy both lists, now starting from the first list:

So first let’s try by setting the variable copy to our original list, list_1:

copy=list_1

Now if you are thinking copy copied the list_1, then you are wrong. The id function can show us if two variables can point to the same object. Let’s try this:

print(id(copy))
print(id(list_1))

The output is:

4329485320
4329485320

Both variables are the exact same argument. Are you surprised?

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 a list but we created two references to that same object by two different variable names. This means that both variables are pointing to the same object, just with different names.

When you do copy=list_1, it is actually doing:

enter image description here

Here in the image list_1 and copy are two variable names but the object is same for both variable which is list

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:

copy[0]="modify"

print(copy)
print(list_1)

output:

['modify', '98']
['modify', '98']

So it modified the original list :

Now let’s move onto a pythonic method for copying lists.

copy_1=list_1[:]

This method fixes the first issue we had:

print(id(copy_1))
print(id(list_1))

4338792136
4338791432

So as we can see our both list having different id and it means that both variables are pointing to different objects. So what actually going on here is:

enter image description here

Now let’s try to modify the list and let’s see if we still face the previous problem:

copy_1[0]="modify"

print(list_1)
print(copy_1)

The output is:

['01', '98']
['modify', '98']

As you can see, it only modified the copied list. That means it worked.

Do you think we’re done? No. Let’s try to copy our nested list.

copy_2=list_2[:]

list_2 should reference to another object which is copy of list_2. Let’s check:

print(id((list_2)),id(copy_2))

We get the output:

4330403592 4330403528

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:

copy_2[0][1]="modify"

print(list_2,copy_2)

This gives us the output:

[['01', 'modify']] [['01', 'modify']]

This may seem a little bit confusing, because the same method we previously used worked. Let’s try to understand this.

When you do:

copy_2=list_2[:]

You’re only copying the outer list, not the inside list. We can use the id function once again to check this.

print(id(copy_2[0]))
print(id(list_2[0]))

The output is:

4329485832
4329485832

When we do copy_2=list_2[:], this happens:

enter image description here

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 as the nested list object is same for both lists.

What is the solution? The solution is the deepcopy function.

from copy import deepcopy
deep=deepcopy(list_2)

Let’s check this:

print(id((list_2)),id(deep))

4322146056 4322148040

Both outer lists have different IDs, let’s try this on the inner nested lists.

print(id(deep[0]))
print(id(list_2[0]))

The output is:

4322145992
4322145800

As you can see both IDs are different, meaning we can assume that both nested lists are pointing different object now.

This means when you do deep=deepcopy(list_2) what actually happens:

enter image description here

Both nested lists are pointing different object and they have separate copy of nested list now.

Now let’s try to modify the nested list and see if it solved the previous issue or not:

deep[0][1]="modify"
print(list_2,deep)

It outputs:

[['01', '98']] [['01', 'modify']]

As you can see, it didn’t modify the original nested list, it only modified the copied list.

Related Articles