list.copy()

A new list, same items — the cure for accidental aliasing, with a shallow-copy caveat.

List methodPython 3.3+Live demo
Common call
snapshot = items.copy()
Returns
new list — mutating it leaves the original alone
Replaces
b = a does NOT copy — both names point at one list
Watch out
shallow: nested lists/dicts are still shared
list.copy()
list

Demo

Live evaluation
Try:
Inputs
listlistcomma-separated items
Output
['a', 'b', 'c'].copy()
['a', 'b', 'c']

The result looks identical — the point is that it is a DIFFERENT list object: appending to the copy leaves the original untouched. Nested objects inside are shared though (shallow copy).

Common patterns

Snapshot before mutating
Iterate the copy while mutating the original (or vice versa).
for item in items.copy():
    if bad(item):
        items.remove(item)
Defensive copies at boundaries
Return a copy so callers cannot mutate your internal state.
def get_items(self):
    return self._items.copy()
The equivalent spellings
copy(), slicing and the constructor produce the same shallow copy.
b = a.copy()
b = a[:]
b = list(a)

Examples

1. Independent top level
a = [1, 2] b = a.copy() b.append(3) a
Returns
[1, 2]
2. Assignment is NOT a copy
a = [1, 2] b = a b.append(3) a
Returns
[1, 2, 3]
3. Nested objects are shared
a = [[1], [2]] b = a.copy() b[0].append(9) a
Returns
[[1, 9], [2]]

Pitfalls

1. b = a is aliasing, not copying
Both names refer to one list; mutations show up under both.
Alias
b = a
b.append(x)  # a changed too!
one list, two names
Fix
b = a.copy()
b.append(x)
independent lists
2. Shallow means nested objects are shared
copy duplicates the list, not what the items point at.
Shared inner
b = a.copy()
b[0].append(9)
# a[0] changed too
inner lists are the same objects
Deep copy
import copy
b = copy.deepcopy(a)
fully independent

When to use

Use it
  • Snapshot a flat list before mutating
  • Defensive copies across API boundaries
  • Iterate-while-removing safely
Reach for something else
  • Nested structures needing independence → copy.deepcopy
  • Just iterating without mutation → no copy needed
  • Copy with transformation → a comprehension does both

Notes

Complexity
O(n) — copies n references
Return
new list; items shared
CPython impl
Objects/listobject.c :: list_copy_impl
Memory
One new array of n pointers
Thread-safe
The copy itself is atomic in CPython

FAQ

No — all three produce the same shallow copy. copy() is the most readable; [:] predates it; list(a) also converts other iterables.

History

3.3
list.copy() added — before that, a[:] and list(a) were the only spellings.