Well, TIL python list just store the pointer to the actually list in memory. So simple list assignment does not make new list!

1
2
3
4
5
list_a = [1,2,3,4]
list_b = list_a
list_b[2] = 10
print(list_a)
print(list_b)

You’ll find above code generate same results:

1
2
[1,2,10,4]
[1,2,10,4]

If we want to make a new copy of list, there is a post in stack overflow that gives several ways. To me it’s actually two types of copy, for simple list (e.g. not nested, or not contain class object), just using list built in copy or is alternative (slicing, list(), copy.copy()), it’s fast, and it’s shallow copy, which means it does not handle nested or complex object. For example

1
2
3
4
5
6
7
8
9
10
11
12
list_shallow = [1,2,3,4]
list_shallow_copy = list_shallow.copy()
list_nested = [1,2,[3,4],5]
list_nested_copy = list_nested.copy()

list_b[2] = 10
print(list_a)
print(list_b)

list_nested_copy[2][0] = 10
print(list_nested)
print(list_nested_copy)

This will generate output:

1
2
3
4
[1,2,3,4]
[1,2,10,4]
[1,2,[10,4],5]
[1,2,[10,4],5]

We can see built in copy() can only handle shallow list, for nested list (or more complex version we should using deepcopy:

1
2
3
4
5
6
7
import copy
list_nested = [1,2,[3,4],5]
list_nested_copy = copy.deepcopy(list_nested)

list_nested_copy[2][0] = 10
print(list_nested)
print(list_nested_copy)

This will generate correct output:

1
2
[1,2,[3,4],5]
[1,2,[10,4],5]

However, deepcopy is the slowest method, but it is sometimes inevitable.


Comments

2019-04-03