DEV Community

Cover image for How to copy a list in Python
cuongld2
cuongld2

Posted on

How to copy a list in Python

In programming, we work a lot with "list" data structure.
Some might run into the issues when working with "list" in Python.
Often times we would like to copy a list to another variable to reuse.
So how do we do that in Python?

1.Wrong way:

old_list = ["Donald is a guy", "Sunshine", 3]
new_list = old_list

Enter fullscreen mode Exit fullscreen mode

If we do this, it actually create a new variable "new_list" which points to the exact memory of old_list.
So when we change the value of old_list or new_list, both list will be changed.


old_list.append("Parapara")
new_list.append("akaka")
print(new_list)
print(old_list)

Enter fullscreen mode Exit fullscreen mode

Alt Text

2.Correct way:

To copy a list, we need to make a slice that includes the entire original list by omitting the first index and the second index ([:]).


old_list = ["Donald is a guy", "Sunshine", 3]
new_list = old_list[:]

Enter fullscreen mode Exit fullscreen mode

Then we append new item to the list


old_list.append("Parapara")
new_list.append("akaka")
print(new_list)
print(old_list)

Enter fullscreen mode Exit fullscreen mode

Let's see the result:

Alt Text

That's it.
Happy coding!!!

Discussion (9)

Collapse
delta456 profile image
Swastik Baranwal

You can also use copy.copy() and copy.deepcopy().

Collapse
muhimen123 profile image
Muhimen

Yeah, I was thinking about that.

newlist = oldlist.copy()

Collapse
delta456 profile image
Swastik Baranwal

copy is a module where copy is a function not a method.

Thread Thread
paddy3118 profile image
Paddy3118

list objects have a .copy method.

Thread Thread
delta456 profile image
Swastik Baranwal

Yeah but I meant my how my example works. 😅

Collapse
rhymes profile image
rhymes

Hi @cuongld2 !

Another way is to use the unpacking operator:

>>> ls1 = list(range(10))
>>> ls1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ls2 = [*ls1]
>>> ls2
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> id(ls1), id(ls2)
(4315161728, 4315161152)

Don't forget you're performing a shallow copy though, if the list contains an object, you're sharing the same object between the original list and the copy:

>>> ls3 = [ls1]
>>> ls4 = ls3[:]
>>> ls3, ls4
([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]], [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
>>> ls4[0].append(10)
>>> ls3, ls4
([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]], [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]])

as you can see now both lists, the original and the copy, have been modified, this is because the list contain a share object (the list ls1). If you want a deep copy you can use copy.deepcopy():

>>> ls3 = [list(range(5))]
>>> import copy; ls4 = copy.deepcopy(ls3)
>>> ls3, ls4
([[0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4]])
>>> ls4[0].append(10)
>>> ls3, ls4
([[0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4, 10]])

There are limitations to what it can "deepcopy", the documentation contains further details.

Collapse
paddy3118 profile image
Paddy3118

Please don't use list unpacking for the sole purpose of creating a shallow copy of a list. Lists have a .copy method that should be used.

Collapse
rhymes profile image
rhymes

I agree, my fault :) I was enumerating the various options :)

Collapse
agtoever profile image
agtoever

There are several other options, listed here, in which I find the new_list = old_list.copy() the most clear in intention and the most readable.