Copying nested lists in Python

Question:

I want to copy a 2D list, so that if I modify one list, the other is not modified.

For a one-dimensional list, I just do this:

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

And now if I modify b, a is not modified.

But this doesn’t work for a two-dimensional list:

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

If I modify b, a gets modified as well.

How do I fix this?

Asked By: SuperString

||

Answers:

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

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

import copy
b = copy.deepcopy(a)
Answered By: Ayman Hourieh

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)

Answered By: Tushar

You can use the following for two-dimensional nested arrays:
b = [[y for y in x] for x in a]

Answered By: Mohanraj Dhanagopal
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.