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)
10.59 sec (105.9us/itn) -
copy.deepcopy(old_list)
10.16 sec (101.6us/itn) - pure python
Copy()
method copying classes with deepcopy1.488 sec (14.88us/itn) - pure python
Copy()
method not copying classes (only dicts/lists/tuples)0.325 sec (3.25us/itn) -
for item in old_list: new_list.append(item)
0.217 sec (2.17us/itn) -
[i for i in old_list]
(a list comprehension)0.186 sec (1.86us/itn) -
copy.copy(old_list)
0.075 sec (0.75us/itn) -
list(old_list)
0.053 sec (0.53us/itn) -
new_list = []; new_list.extend(old_list)
0.039 sec (0.39us/itn) -
old_list[:]
(list slicing)
b = [x[:] for x in a]