Don’t Get Caught Out! Understanding How to Copy Lists in Python
Learn why simply assigning a list to a new variable doesn’t create a true copy and discover the techniques for making independent copies of your lists. …
Updated August 26, 2023
Learn why simply assigning a list to a new variable doesn’t create a true copy and discover the techniques for making independent copies of your lists.
In Python, lists are incredibly versatile data structures. They allow you to store collections of items in a specific order. But there’s a crucial detail about lists that often trips up beginners: assignment doesn’t create copies.
The Problem with Simple Assignment:
Imagine you have a list called my_list
:
my_list = [1, 2, 3]
new_list = my_list
You might think that new_list
now holds its own separate copy of the list. However, this isn’t true! Both my_list
and new_list
are actually pointing to the same list in memory.
If you modify new_list
, you’ll also be modifying my_list
:
new_list.append(4)
print(my_list) # Output: [1, 2, 3, 4]
As you can see, the change to new_list
affected my_list
because they share the same underlying data.
Creating True Copies:
To avoid this issue and have independent copies of lists, we need to use specific copying techniques:
1. Slicing:
Slicing allows us to create a new list containing all the elements of the original list. This creates a shallow copy:
my_list = [1, 2, 3]
new_list = my_list[:] # Slice from beginning to end
print(new_list) # Output: [1, 2, 3]
This method works well for lists containing only simple data types (like integers, strings). However, if your list contains mutable objects like other lists or dictionaries, changes made within those nested objects will still affect both lists.
2. The copy()
Method:
Python’s built-in list.copy()
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]
Like slicing, copy()
is suitable for lists with simple data types but doesn’t create a fully independent copy if the list contains nested mutable objects.
3. The deepcopy()
Function (from the copy
Module):
For a truly independent copy that handles nested mutable objects, use the deepcopy()
function from the copy
module:
import copy
my_list = [1, 2, [3, 4]]
new_list = copy.deepcopy(my_list)
# Modify the nested list in 'new_list'
new_list[2][0] = 5
print(my_list) # Output: [1, 2, [3, 4]] (original unchanged)
print(new_list) # Output: [1, 2, [5, 4]]
Choosing the Right Method:
Use slicing (
[:]
) orcopy()
when dealing with lists containing only simple data types.Use
deepcopy()
when your list contains nested mutable objects (lists, dictionaries, etc.) and you need a completely independent copy.