Editor

Python Program to Copy a List

Beginner · Lists

Writing b = a does not copy a list: it gives the same list a second name, so a change through one name shows up through the other. This program shows that trap, then makes a shallow copy and a deep copy, and shows why a list that holds other lists needs a deep copy.

Program

copy_a_list.py
import copy
# 1. Assignment does not copy: both names point to the same list
original = [1, 2, 3]
alias = original
alias.append(4)
print("original after alias.append(4):", original)
# 2. A shallow copy is a new outer list...
marks = [[90, 85], [70, 65]]
shallow = marks.copy() # same as list(marks) or marks[:]
shallow.append([50, 55])
print("marks after shallow.append():", marks)
# ...but the inner lists are still shared
shallow[0][0] = 0
print("marks after shallow[0][0] = 0:", marks)
# 3. A deep copy copies the inner lists too
marks = [[90, 85], [70, 65]]
deep = copy.deepcopy(marks)
deep[0][0] = 0
print("marks after deep[0][0] = 0:", marks)
print("deep:", deep)
Output
original after alias.append(4): [1, 2, 3, 4]
marks after shallow.append(): [[90, 85], [70, 65]]
marks after shallow[0][0] = 0: [[0, 85], [70, 65]]
marks after deep[0][0] = 0: [[90, 85], [70, 65]]
deep: [[0, 85], [70, 65]]

How it works

  1. alias = original makes no copy at all, so appending through alias changes original too.
  2. marks.copy() makes a shallow copy: a new outer list, so appending to shallow leaves marks alone.
  3. The inner lists are not copied, though. shallow[0] and marks[0] are the same list, so setting shallow[0][0] = 0 changes marks as well. This is the shallow copy trap.
  4. copy.deepcopy() copies the inner lists too, so changing deep never touches marks.
  5. For a flat list of numbers or strings, a shallow copy is all you need; use a deep copy when the list holds other lists or dictionaries.

Other ways to write it

Three ways to make a shallow copy

Three ways to make a shallow copy
numbers = [5, 10, 15]
a = numbers.copy()
b = list(numbers)
c = numbers[:]
a.append(20)
print("numbers:", numbers)
print("a:", a, "| b:", b, "| c:", c)
print("Is a the same list as numbers?", a is numbers)
Output
numbers: [5, 10, 15]
a: [5, 10, 15, 20] | b: [5, 10, 15] | c: [5, 10, 15]
Is a the same list as numbers? False

copy(), list() and the full slice [:] all make a new list, and is confirms that a is a different object from numbers.

Copying each row of a list of lists

Copying each row of a list of lists
grid = [[1, 2], [3, 4]]
grid_copy = [row.copy() for row in grid] # copy every inner list
grid_copy[1][1] = 99
print("grid:", grid)
print("grid_copy:", grid_copy)
Output
grid: [[1, 2], [3, 4]]
grid_copy: [[1, 2], [3, 99]]

Copying every row by hand is enough for a list of lists one level deep; copy.deepcopy() handles any depth.

Try it yourself

Replace copy.deepcopy(marks) with marks[:] and see the shallow copy trap come back.

Edit the program above and press Run, or open it in the full editor to save it and share it. To watch it run line by line, open it in the visualizer.

All Python programs · CBSE class 12 practical file · Python exercises