Reputation: 434
I found the way to make a list filled with the same literal.
So I did following:
my_list_of_dict = [{}] * 3
my_list_of_dict[0][0] = 1
my_list_of_dict[0][1] = 2
print(my_list_of_dict)
# What I thought : [{0: 1, 1: 2}, {}, {}]
# What actually happened : [{0: 1, 1: 2}, {0: 1, 1: 2}, {0: 1, 1: 2}]
Is this a bug? or an intended feature?
It seems like python doesn't initialize new dict every time but just assigning given dict to the list.
Plus, How do I call(pronouce) [] * n
? is this a kind of list comprehension?
Upvotes: 2
Views: 58
Reputation: 42746
{}
returns a reference to the dict, and then by *3
you are making 3 references to the same dict
.
To fix this, use a different approach:
[{} for _ in range(3)]
With zeros
(0
) it doesnt matter because they are inmutable so once you modify the value inside the list you are "creating" a new number and then reference it through the list:
>>> l = [0]*3
>>> [id(x) for x in l]
[10910368, 10910368, 10910368]
>>> l[0] = 10
>>> [id(x) for x in l]
[10910688, 10910368, 10910368]
But with mutable objects you are modifiying the object referenced directly, so all the positions in the list are aware of that change, since they point to the same object:
>>> l = [[]]*3
>>> l
[[], [], []]
>>> l[0].append(10)
>>> l
[[10], [10], [10]]
>>> [id(x) for x in l]
[139858640463368, 139858640463368, 139858640463368]
By using the other comprehension, you are creating a new instance in each loop of the comprehension:
>>> l = [{} for _ in range(3)]
>>> l[0]["foo"] = 10
>>> l
[{'foo': 10}, {}, {}]
Upvotes: 5