How to Copy a List in Python (5 Ways + Deep Copy)

Want to copy a list in Python? Call new = old.copy(), or use the slice old[:]. Both give you a separate list, so changing one won’t touch the other. For lists that contain other lists, use copy.deepcopy():

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

import copy
new = copy.deepcopy(nested)

Screenshots come straight from Python 3.12.5 in Command Prompt, with the output text pasted under each code block.

I’ll start with the mistake that makes copying necessary, then show five ways to copy, the shallow vs deep difference, which method is fastest, and copying inside functions.

Why = doesn’t copy a list in Python

Assignment never copies anything. same = cart just puts a second name on the same list, so a change through either name shows up in both:

cart = ["coffee", "bagel", "juice"]
same = cart                 # NOT a copy, just a second name

same.append("muffin")
print("cart:", cart)        # changed too!
print("same object?", same is cart)

Output:

cart: ['coffee', 'bagel', 'juice', 'muffin']
same object? True
Command Prompt output showing a Python list assigned to a second variable and both names changing after append
Appending to same changed cart, because same is cart is True.

This catches almost everyone at first. Mutable vs immutable in Python explains why lists behave this way and strings don’t.

5 ways to copy a list in Python

Each of these gives you a new list with the same items. They’re interchangeable for a flat list of numbers or strings:

import copy

cart = ["coffee", "bagel", "juice"]

a = cart.copy()
b = cart[:]
c = list(cart)
d = copy.copy(cart)
e = [*cart]

a.append("muffin")
print("original:", cart)
print("a:       ", a)
print("all equal and separate:", b == c == d == e == cart, b is not cart)

Output:

original: ['coffee', 'bagel', 'juice']
a:        ['coffee', 'bagel', 'juice', 'muffin']
all equal and separate: True True
Command Prompt output of five Python list copy methods: copy(), slicing, list(), copy.copy() and unpacking
Appending to a left the original alone. All five copies are equal to it but separate objects.
MethodCodeNotes
list.copy()new = old.copy()Clearest; what I use
Slicenew = old[:]Classic, very common in older code
list()new = list(old)Also converts tuples, sets, etc.
copy.copy()new = copy.copy(old)Works on any object
Unpackingnew = [*old]Handy when adding items too

Shallow copy vs deep copy of a list

Every method above makes a shallow copy. The outer list is new, but the items inside are shared. With nested lists, that means the inner lists are shared:

import copy

orders = [["Austin", 2], ["Denver", 5]]

shallow = orders.copy()
deep = copy.deepcopy(orders)

orders[0][1] = 99                # change something inside an inner list
orders.append(["Boston", 1])     # and add a new row

print("original:", orders)
print("shallow: ", shallow)      # inner list is shared, new row isn't
print("deep:    ", deep)         # fully independent
print(shallow[0] is orders[0], deep[0] is orders[0])

Output:

original: [['Austin', 99], ['Denver', 5], ['Boston', 1]]
shallow:  [['Austin', 99], ['Denver', 5]]
deep:     [['Austin', 2], ['Denver', 5]]
True False
Command Prompt output comparing a shallow copy and copy.deepcopy of a nested Python list after changing an inner value
The shallow copy picked up the 99 because it shares the inner list. The deep copy didn’t change at all.

Appending a new row didn’t affect either copy, since that only changes the outer list. For the full picture, see shallow copy vs deep copy in Python and list of lists in Python.

Which way to copy a list is fastest?

For a flat list, the built-in methods are all quick. deepcopy() is far slower because it inspects every item, so only use it when you need it:

import copy
import timeit

data = list(range(1_000))
tests = {
    "list.copy()": lambda: data.copy(),
    "data[:]": lambda: data[:],
    "list(data)": lambda: list(data),
    "copy.copy()": lambda: copy.copy(data),
    "copy.deepcopy()": lambda: copy.deepcopy(data),
    "comprehension": lambda: [x for x in data],
}
for name, fn in tests.items():
    t = timeit.timeit(fn, number=2_000)
    print(f"{name:<16} {t * 1000:8.2f} ms")

Output:

list.copy()          2.74 ms
data[:]              2.81 ms
list(data)           3.33 ms
copy.copy()          2.86 ms
copy.deepcopy()    322.55 ms
comprehension       23.68 ms
Command Prompt timing comparison of Python list copy methods with timeit, showing deepcopy is much slower
copy(), slicing and list() are neck and neck. Your exact numbers will vary.

Copying a list inside a function

Python passes the list itself into your function, not a copy. If your function changes it, the caller sees the change. Copy first when you want to leave the original alone:

def add_tax(prices, rate=0.08):
    prices = prices.copy()             # work on a copy so the caller's list is safe
    for i, p in enumerate(prices):
        prices[i] = round(p * (1 + rate), 2)
    return prices

menu = [4.50, 2.75, 3.25]
print("with tax:", [f"${p:.2f}" for p in add_tax(menu)])
print("menu:    ", [f"${p:.2f}" for p in menu])     # untouched

Output:

with tax: ['$4.86', '$2.97', '$3.51']
menu:     ['$4.50', '$2.75', '$3.25']

Returning a new list like this makes functions easier to test and reason about. The loop uses enumerate() to update each price by position.

For more list skills, try these next:

Frequently asked questions

How do I copy a list in Python?

Use new = old.copy() or new = old[:]. For nested lists, use copy.deepcopy(old).

Why does changing my copy change the original list?

You probably wrote new = old, which doesn’t copy. Or the list is nested and you made a shallow copy.

What’s the difference between copy() and deepcopy()?

copy() copies the outer list only. deepcopy() copies everything inside it too, recursively.

Is list[:] the same as list.copy()?

Yes, for lists they give the same shallow copy. copy() just reads more clearly.

Does deepcopy work on lists of dictionaries?

Yes. It copies the dictionaries and anything inside them, so nothing is shared with the original.

Where is copying documented?

The copy module docs explain shallow and deep copies.