How do I copy a list in Python without changing the original?

Short answer

new = old creates another name for the same list. Use old.copy(), old[:], or list(old) for a shallow copy, and copy.deepcopy(old) when the list contains other mutable objects.

python
old = [1, 2, 3]
new = old
new.append(4)
print(old)      # [1, 2, 3, 4]  — you changed both

Assignment binds a second name to the same object. Nothing was copied.

#Shallow copies

All three are equivalent:

python
new = old.copy()
new = old[:]
new = list(old)

Now new.append(4) leaves old alone.

#When shallow is not enough

A shallow copy copies the outer list but shares whatever is inside it:

python
grid = [[1, 2], [3, 4]]
copy = grid[:]
copy[0].append(99)
print(grid)      # [[1, 2, 99], [3, 4]]  — the inner list was shared

For nested structures, use deepcopy:

python
import copy
independent = copy.deepcopy(grid)

deepcopy is slow and recurses through the whole structure, so use it only when you need it.

#The multiplication trap

This bites people building grids:

python
grid = [[0] * 3] * 3      # three references to ONE row
grid[0][0] = 1
print(grid)               # [[1,0,0], [1,0,0], [1,0,0]]

Use a comprehension instead, which evaluates the inner list each time:

python
grid = [[0] * 3 for _ in range(3)]