Copying a list using assignment instead of copy()

Loading

In Python, lists are mutable, meaning their contents can be changed. A common mistake occurs when you try to copy a list using assignment (=) instead of using the copy() method or copy module. This leads to unexpected behavior, where modifying one list affects the other because both refer to the same memory location.

Let’s go step by step to understand the issue and how to avoid it.


1. Understanding List Assignment (=)

When you assign a list to another variable using =, you are not creating a new list; instead, you are creating a reference to the same list in memory.

Example: Incorrect List Copying Using =

list1 = [1, 2, 3, 4]
list2 = list1 # Creates a reference, not a copy

list2.append(5) # Modifying list2 also affects list1
print(list1) # Output: [1, 2, 3, 4, 5]
print(list2) # Output: [1, 2, 3, 4, 5]

Problem:

  • list1 and list2 share the same memory address.
  • Any modification to list2 also modifies list1, which is usually not intended.

Check Memory Address

print(id(list1))  # Memory address of list1
print(id(list2)) # Memory address of list2 (same as list1)

2. Correct Ways to Copy a List

Method 1: Using copy() (Shallow Copy)

The built-in copy() method creates a new list but only copies the outer elements (shallow copy).

list1 = [1, 2, 3, 4]
list2 = list1.copy() # Proper copy

list2.append(5)
print(list1) # Output: [1, 2, 3, 4] (Unchanged)
print(list2) # Output: [1, 2, 3, 4, 5] (New list)

Memory addresses are different:

print(id(list1))  # Different memory address
print(id(list2))

Method 2: Using list() Constructor

Another way to create a shallow copy is using list().

list1 = [1, 2, 3, 4]
list2 = list(list1) # Creates a copy

list2.append(5)
print(list1) # [1, 2, 3, 4] (Unchanged)
print(list2) # [1, 2, 3, 4, 5] (New list)

Method 3: Using Slicing ([:])

A simple and efficient way to copy a list is using slicing.

list1 = [1, 2, 3, 4]
list2 = list1[:] # Copies all elements

list2.append(5)
print(list1) # [1, 2, 3, 4]
print(list2) # [1, 2, 3, 4, 5]

3. Deep Copying (for Nested Lists)

A shallow copy works for simple lists, but for nested lists (lists within lists), you need a deep copy.

Example of Shallow Copying a Nested List

list1 = [[1, 2], [3, 4]]
list2 = list1.copy() # Shallow copy (nested lists are still linked)

list2[0][0] = 100 # Modifies list1 too!
print(list1) # [[100, 2], [3, 4]]
print(list2) # [[100, 2], [3, 4]]

Problem: The outer list is copied, but nested lists still share the same reference.

Method 4: Using copy.deepcopy() for Nested Lists

For nested lists, use copy.deepcopy() from the copy module.

import copy

list1 = [[1, 2], [3, 4]]
list2 = copy.deepcopy(list1) # Deep copy

list2[0][0] = 100
print(list1) # [[1, 2], [3, 4]] (Unchanged)
print(list2) # [[100, 2], [3, 4]]

Deep copy ensures that all nested lists are fully copied and do not reference the original.


4. Summary of Copying Methods

MethodTypeWorks for Nested Lists?Creates a New Memory Address?
= (Assignment) ReferenceNoNo
.copy() Shallow CopyNoYes (outer list only)
list() Shallow CopyNoYes (outer list only)
[:] (Slicing) Shallow CopyNoYes (outer list only)
copy.deepcopy() Deep CopyYesYes (fully independent)

Leave a Reply

Your email address will not be published. Required fields are marked *