There will be times when you might want to copy a list in Python. For instance, if you’re going to keep the original list untouched. Instead, you may want to perform some operations on the copied list or maybe some other operations.
The following article covers the difference between shallow and deep copy, ways to copy a list and a nested list in Python.
Shallow Vs. Deep Copy in Python
Before establishing the difference between shallow and deep copy, we would like to talk about immutability and mutability in Python.
As the name suggests, immutable objects can’t be altered, and therefore, Python will instead create a new object when the value of such object is modified. However, mutable objects can be altered.
Immutable objects: int, string, tuple
Mutable objects: list, sets, dictionary
Immutability and mutability in Python
# int objects in python are immutable
a = 10
b = a
a += 10
print(f"Values: a = {a}, b = {b}")
print(f"{id(a) == id(b)}")
# However, list objects in python are mutable
l1 = [[1],[2],[3]]
l2 = l1
l1[0][0] = 10
print(f"\nValues: l1 = {l1}, l2 = {l2}")
print(f"{id(l1) == id(l2)}")
Python provides two ways to copy a list; these are:
- Shallow copy
- Deep copy
Let’s understand the difference between them.
Shallow Copy
In shallow copy, an object is created that then gets populated with the references of the items of the original list. One level of deep copying occurs in shallow copy. A shallow copy of the list is created using the copy method of the copy module. However, there are other ways too. Let’s understand this using an example.
import copy
list1 = [[1,2,3],[4,5,6],[7,8,9]]
list2 = copy.copy(list1)
list1[0][0] = 101
print(f"list1:{list1}\nlist2:{list2}")
Deep Copy
While in the case of deep copy, it recursively copies the items found in the original list to the new object. This way, it creates a clone/copy of the original list. A deep copy of the list can be created using the deep copy method of the copy module.
import copy
list1 = [[1,2,3],[4,5,6],[7,8,9]]
list2 = copy.deepcopy(list1)
list1[0][0] = 101
print(f"list1:{list1}\nlist2:{list2}")
You can read more about shallow and deep copy operations from here.
List Copy Methods in Python
Using the list method
List constructor of Python can create a copy of a list.
list1 = [[2,4,6],[3,6,9],['erwin','levi','hange']]
list2 = list(list1)
print(f"list1:{list1}\nlist2:{list2}")
Using the ‘ = ‘ operator
The assignment = operator can create a copy of a list.
list1 = [[21,24,66],[233,26,69],['kevin', 'ben']]
list2 = list1
print(f"list1:{list1}\nlist2:{list2}")
Using the list slicing
Python’s list slicing is used to create a copy of a list.
list1 = [[1,2,3],[4,5,6],[7,8,9]]
list2 = list1[:]
print(f"list1:{list1}\nlist2:{list2}")
Copy list except for the last element
In order to get a list without the last element, you can do the following:
list1 = [[1,2,3],[4,5,6],[7,8,9]]
list2 = list1[:-1]
print(f”list1:{list1}\nlist2:{list2}”)
Using the list comprehension
Similarly, Python’s list comprehension is used to create a copy of a list.
list1 = [[2,4,6],[3,6,9],[4,8,12]]
list2 = [item for item in list1]
print(f"list1:{list1}\nlist2:{list2}")
Using the extend method
Python’s extend method can create a copy of a list.
list1 = [[2,4,6],[3,6,9],[4,8,12]]
list2 = []
list2.extend(list1)
print(f"list1:{list1}\nlist2:{list2}")
Using the append method
Similarly, Python’s append method can also create a copy of a list.
list1 = [[12,14,6],[13,16,19],[14,81,112]]
list2 = []
list2.append(list1)
print(f"list1:{list1}\nlist2:{list2}")
Copying a list multiple times
We can easily create multiple copies of a list. Let’s go through the different methods:
Using the ‘ * ‘ operator
This method creates a shallow copy.
l1 = [[1,2,3,4,5]]
num_of_copies = int(input("Enter the number of copies:"))
l2 = l1 * num_of_copies
print(l2)
Using the list comprehension
l1 = [1,2,3,4,5]
num_of_copies = int(input("Enter the number of copies:"))
l2 = [l1 for _ in range(num_of_copies)]
print(l2)
Using the itertools repeat method
from itertools import repeat
num_of_copies = int(input("Enter the number of copies:"))
l = [1,2,3,4]
l_copy = list(repeat(l,num_of_copies))
print(l_copy)
FAQs on Copy List in Python
Deep copy in Python recursively copies the items found in the original list to the new object. This way, it creates a clone/copy of the original list.
In shallow copy, an object is created that then gets populated with the references of the items of the original list. One level of deep copying occurs in shallow copy.
By using the copy module’s deepcopy method. For instance: from copy import deepcopy
list1 = [[1,2,3],[4,5,6],[7,8,9]]
list2 = deepcopy(list1)
print(f"list1:{list1}\nlist2:{list2}")
list1:[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
list2:[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
We can convert a generator to a list using the list method. For instance:l = [[1,2,3],[4,5,6],[7,8,9]]
list l converted to a generator
gen_l = (elem for elem in l)
to convert generator to a list
gen_l_to_list = list(gen_l)
print(gen_l_to_list)
We can convert a queue to a list using the list method. For instance:from collections import deque
que = deque()
que.append('tangiro')
que.append('nezko')
print(f"que: {que}\nType: {type(que)}")
que_list = list(que)
print(f"\nque_list: {que}\nType: {type(que_list)}")
Conclusion
It is important to realize the distinction between shallow and deep copy. Accordingly, both have different use cases. We discussed different ways for copying a list in Python, for instance, using the list method, = operator, list comprehension, etc. I hope you have learned something new today.