A list in python is a collection of elements of same or different types and is created by enclosing the elements inside square brackets.
Often you need to make a copy of an existing list so that you can modify some elements of the copy without actually modifying the original list.

Simply assigning a list to another new list will definitely create two lists with identical elements but the second list will not be an ideal copy since changes made to the copied list will also reflect in the original list.
Example,

original_list = [1, 2, 3]
# assign existing list to a new list
copy_list = original_list
# modify first element of copy
copy_list[0] = 2
# print original list
print(original_list)      # prints [2, 2, 3]

As you can see the original list is also modified.
This post will explain different ways to clone or copy a list in python so that changes made to any of the lists are independent of each other.

1. copy() method

Use inbuilt function copy() of list class to create its clone.
This method takes an object which is the object whose copy needs to be created and returns a new object with contents of the supplied object.
Since the returned list is a new object, changes made to it are not reflected in the original object.
Example,

original_list = [1, 2, 3]
# create a new copy using copy function
copy_list = original_list.copy()
# modify first element of copy
copy_list[0] = 2
# print original list
print(original_list)    # prints [1, 2, 3]
# print copied list
print(copy_list)        # prints [2, 2, 3]
To confirm that original and copy list are two separate lists that point to different memory locations, use the comparison operator as original_list == copy_list.
If the lists are different, it will return False.

2. List slicing

Slicing operator(:) when used without any arguments on its left and right returns a new object with the entire contents of the original list.
New object is a different object and thus any changes made to it will be limited to that object only.
Example,

original_list = [1, 2, 3]
# create new copy using slicing
copy_list = original_list[:]
# modify first element of copy
copy_list[0] = 2
# print original list
print(original_list)    # prints [1, 2, 3]
# print copied list
print(copy_list)        # prints [2, 2, 3]

3. list() function

Python’s builtin function list() can also be used to create a new list object.
It takes another list object as argument and returns a new list with its contents populated from the supplied list.

original_list = [1, 2, 3]
# create new copy using list function
copy_list = list(original_list)
# modify first element of copy
copy_list[0] = 2
# print original list
print(original_list)    # prints [1, 2, 3]
# print copied list
print(copy_list)        # prints [2, 2, 3]

Python docs for list function state

list(iterable) -> new list initialized from iterable’s items

If no argument is supplied to list function, it will return a new list with empty contents.

4. copy() method from copy module

Python’s copy module can be used to perform copy operations. Its copy method takes an object as argument and returns a new object whose contents are exact copy of the supplied object.
For using this function, you need to import copy module first.
Example,

import copy

original_list = [1, 2, 3]
# create new copy
copy_list = copy.copy(original_list)
# modify first element of copy
copy_list[0] = 2
# print original list
print(original_list)     # prints [1, 2, 3]
# print copied list
print(copy_list)         # prints [2, 2, 3]

5. deepcopy() from copy module

All the above methods perform a shallow copy of the list.

Shallow and deep copy differ only when the object to be copied contains other nested object. Nested object means object inside another object.
Example,
if a Student object contains an Address object, then Address object is a nested object.

In case of shallow copy, a separate copy of outer object is made while inner objects are copied as it is(same objects are used) while in deep copy operation, nested objects are also separately copied.
copy module’s deepcopy method can be used to perform deep copy of the supplied list.

If the list contains only numbers, string or any non-nested objects, then this method should not be used as it is comparatively slower.
In that case, any of the above methods can be used.
Example,

import copy

original_list = [1, 2, 3]
# create deep copy
copy_list = copy.deepcopy(original_list)
# modify first element of copy
copy_list[0] = 2
# print original list
print(original_list)    # prints [1, 2, 3]
# print copied list
print(copy_list)        # prints [2, 2, 3]

For using this method, you need to import copy module first.

6. List iteration

This is a traditional method where we iterate over the source list and add its elements to the copy list(which is initially an empty list) one by one.
The new list created this way will be a separate list than the source list and thus, any changes made to the new list will not affect the original list.
Example,

# create empty list
copy_list = []
# iterate over the source list
for element in original_list:
  # add element to new list
  copy_list.append(element)
# modify first element of copy
copy_list[0] = 2
# print original list
print(original_list)   # prints [1, 2, 3]
# print copied list
print(copy_list)       # prints [2, 2, 3]

As evident, modifying the new list element does not affect the original list.

7. List comprehension

Python list comprehension can also be used to clone a list as shown below

original_list = [1, 2, 3, 4, 5]
# copy list
copy_list = [item for item in original_list]
# modify original list 
original_list[0] = 2
# print both lists
print(original_list)
print(copy_list)

Above code iterates over each element in the original_list and creates a new list (copy_list) with the same elements. The new list is independent copy of the original list.

Hope the article was useful.

Leave a Reply