Copying nested lists in Python

For a more general solution that works regardless of the number of dimensions, use copy.deepcopy():

import copy
b = copy.deepcopy(a)

Whis b = a[:] doesn't work for nested list(or say muti-dimension list)?

a = [[1, 2],[3, 4]]
b = a[:]

Answer: Though when we are copying the list a using slicing[:] operation but the inner sub-list still refers to the inner-sub list of list b
Note: We can check the reference using id() in python.
Let's understand using an example.

>>> a = [[1,2],[3,4]]
>>> id(a)
140191407209856    # unique id of a
>>> b=a
>>> id(b)
140191407209856
>>> b=a[:]        # Copying list a to b with slicing
>>> id(b)         
140191407209920   # id of list b changed & is not same as id of list a
>>> id(a[0])      
140191407188544
>>> id(b[0])
140191407188544
>>> id(a[0])==id(b[0])  # id of both a[0] & b[1] is same.
True

So, slicing won't change the reference for objects inside the list. You can notice from above that reference of a[0] is the same as b[0].
When you copy a 2D list to another, it adds a reference to it not the actual list.
Instead you can use:

  • b = copy.deepcopy(a)
  • b = [item[:] for item in a]
  • b = [item.copy() for item in a]
  • b = [list(item) for item in a]
  • b = [copy.copy(item) for item in a]
  • b = []; b.extens[a]

Below is the comparison of the time complexity of all available copy methods (source)

  1. 10.59 sec (105.9us/itn) - copy.deepcopy(old_list)

  2. 10.16 sec (101.6us/itn) - pure python Copy() method copying classes with deepcopy

  3. 1.488 sec (14.88us/itn) - pure python Copy() method not copying classes (only dicts/lists/tuples)

  4. 0.325 sec (3.25us/itn) - for item in old_list: new_list.append(item)

  5. 0.217 sec (2.17us/itn) - [i for i in old_list] (a list comprehension)

  6. 0.186 sec (1.86us/itn) - copy.copy(old_list)

  7. 0.075 sec (0.75us/itn) - list(old_list)

  8. 0.053 sec (0.53us/itn) - new_list = []; new_list.extend(old_list)

  9. 0.039 sec (0.39us/itn) - old_list[:] (list slicing)


b = [x[:] for x in a]