In Python, when you assign a new variable to an existing list using the assignment operator (=), it does not create a new independent copy of the list. Instead, both variables point to the same memory location, which can lead to unexpected behavior when modifying the list through one of the variables.
This tutorial will explore why this happens and provide several methods for cloning lists in Python, including using built-in methods, slicing, and the copy
module.
Why Lists Are Not Cloned by Assignment
When you assign a new variable to an existing list using the assignment operator (=), Python creates a new reference to the same object. This means that both variables point to the same memory location where the original list is stored.
For example:
my_list = [1, 2, 3]
new_list = my_list
print(id(my_list)) # Output: some memory address (e.g., 43218112)
print(id(new_list)) # Output: same memory address as above (e.g., 43218112)
As you can see, both my_list
and new_list
have the same memory address, which means they are referencing the same list object.
Cloning Lists Using Built-in Methods
Python provides several built-in methods for cloning lists:
- Using the
copy()
method: Available since Python 3.3, this method creates a shallow copy of the list.
my_list = [1, 2, 3]
new_list = my_list.copy()
print(new_list) # Output: [1, 2, 3]
- Using slicing: This method also creates a shallow copy of the list.
my_list = [1, 2, 3]
new_list = my_list[:]
print(new_list) # Output: [1, 2, 3]
- Using the
list()
constructor: This method creates a new list from an existing iterable (like another list).
my_list = [1, 2, 3]
new_list = list(my_list)
print(new_list) # Output: [1, 2, 3]
Cloning Lists Using the copy
Module
The copy
module provides two functions for cloning lists:
- Using
copy.copy()
: This function creates a shallow copy of the list.
import copy
my_list = [1, 2, 3]
new_list = copy.copy(my_list)
print(new_list) # Output: [1, 2, 3]
- Using
copy.deepcopy()
: This function creates a deep copy of the list, recursively copying any nested lists or other mutable objects.
import copy
my_list = [[1], [2], [3]]
new_list = copy.deepcopy(my_list)
print(new_list) # Output: [[1], [2], [3]]
# Modifying new_list does not affect my_list
new_list[0][0] = 'modified'
print(my_list) # Output: [[1], [2], [3]]
Comparison of Cloning Methods
The following table summarizes the cloning methods discussed in this tutorial:
| Method | Shallow Copy? | Deep Copy? |
| — | — | — |
| copy()
method | Yes | No |
| Slicing ([:]
) | Yes | No |
| list()
constructor | Yes | No |
| copy.copy()
function | Yes | No |
| copy.deepcopy()
function | No | Yes |
When choosing a cloning method, consider whether you need a shallow copy (which copies only the references to the original elements) or a deep copy (which recursively copies any nested mutable objects).
In conclusion, this tutorial has covered various methods for cloning lists in Python. By understanding the differences between these methods, you can choose the most suitable approach for your specific use case.