Reputation: 3
I have created a dictionary by using this:
a = dict.fromkeys([round(x*0.1,1) for x in range(10)], [0,0])
it will give me the following results:
>>> a
{0.0: [0, 0], 0.5: [0, 0], 0.2: [0, 0], 0.4: [0, 0], 0.8: [0, 0], 0.6: [0, 0], 0.3: [0, 0], 0.1: [0, 0], 0.9: [0, 0], 0.7: [0, 0]}
I only want to update the second value for key=0.5, for example. I was using the following code:
a[0.5][1]=a[0.5][1]+10
However, it turns out that it updated all second values for all keys.
>>> a
{0.0: [0, 10], 0.5: [0, 10], 0.2: [0, 10], 0.4: [0, 10], 0.8: [0, 10], 0.6: [0, 10], 0.3: [0, 10], 0.1: [0, 10], 0.9: [0, 10], 0.7: [0, 10]}
I'm wondering if there is a way to do that?
Many thanks in advance!
Upvotes: 0
Views: 2544
Reputation: 250951
Don't use dict.fromkeys
with a mutable value, it simply copies the reference to the same list object to all the keys. So, changing any one the reference is going to affect all the lists.
>>> d = dict.fromkeys('abcdef', [])
>>> [id(x) for x in d.values()]
[164654156, 164654156, 164654156, 164654156, 164654156, 164654156]
Use a dict comprehension
instead:
>>> d = {k:[] for k in 'abcdef'}
>>> [id(x) for x in d.values()]
[164621484, 164653580, 164331340, 164653804, 164653900, 164653836]
For your code it is going to be:
a = {round(x*0.1,1): [0, 0] for _ in range(10)}
Upvotes: 4
Reputation: 41898
You're using the same list instance as value for all keys. Instead of:
a=dict.fromkeys([round(x*0.1,1) for x in range(10)], [0,0])
Initialize it like this:
a=dict((round(x*0.1,1), [0, 0]) for x in range(10))
Upvotes: 0
Reputation: 95252
All of the dictionary entries reference the same list. You would be better off creating the dictionary differently:
a = {}
for x in range(10):
a[round(x*0.1,1)] = [0,0]
Upvotes: 0
Reputation: 48546
That because you used the same list for every value in your dict.
Don't use fromkeys
with a mutable value. Use a dict comprehension:
a = {round(x*0.1, 1): [0, 0] for x in range(10)}
Or, if you're stuck with 2.6, a fake dict comprehension:
a = dict((round(x*0.1, 1), [0, 0]) for x in range(10))
Upvotes: 0