Python Tutorial

Copying Lists in Python

In Python, lists are mutable data structures, which means you can change their contents after they have been created. When you assign a list to a variable, you are actually creating a reference to the original list, not a new copy of it. This can lead to unexpected behavior if you're not careful.

Let's look at an example:

original_list = [1, 2, 3]
new_list = original_list
new_list.append(4)
print(original_list)  # Output: [1, 2, 3, 4]
print(new_list)  # Output: [1, 2, 3, 4]

In this example, when we assign original_list to new_list, both variables point to the same underlying list. So, when we modify new_list by appending an element, the changes are reflected in original_list as well.

If you want to create a true copy of a list, you can use one of the following methods:

1. Slice Operator ([:])

The simplest way to create a copy of a list is to use the slice operator [:]. This creates a new list object with the same elements as the original list.

original_list = [1, 2, 3]
new_list = original_list[:]
new_list.append(4)
print(original_list)  # Output: [1, 2, 3]
print(new_list)  # Output: [1, 2, 3, 4]

2. list() Constructor

You can also use the list() constructor to create a new list from an existing one.

original_list = [1, 2, 3]
new_list = list(original_list)
new_list.append(4)
print(original_list)  # Output: [1, 2, 3]
print(new_list)  # Output: [1, 2, 3, 4]

3. copy() Method

The copy() method is another way to create a shallow copy of a list.

original_list = [1, 2, 3]
new_list = original_list.copy()
new_list.append(4)
print(original_list)  # Output: [1, 2, 3]
print(new_list)  # Output: [1, 2, 3, 4]

Deep Copying

The methods above create shallow copies of the list, which means that if the list contains nested objects (like lists within lists), the nested objects are still referenced by both the original and the copied list. If you need to create a deep copy, where all nested objects are also copied, you can use the copy module's deepcopy() function.

import copy

original_list = [[1, 2], [3, 4]]
new_list = copy.deepcopy(original_list)
new_list[0].append(5)
print(original_list)  # Output: [[1, 2], [3, 4]]
print(new_list)  # Output: [[1, 2, 5], [3, 4]]

In this example, modifying the nested list in new_list does not affect the nested list in original_list.

Conclusion

Correctly handling the copying of lists is an important skill in Python programming. By using the slice operator, the list() constructor, the copy() method, or the deepcopy() function from the copy module, you can create copies of lists that behave independently from the original, avoiding unintended side effects.