emacsbeginner
emacsbeginner

Reputation: 11

Python: Appending to a list, which is value of a dictionary

Here is the code, which I would like to understand. I am creating a dict using elements of a list as keys and another list as default values. Then update this dict with another one. Finally, I would like to append to the list within dict. The append is happening multiple times for some of the elements. I would like append to happy only once for each of the values of dict.

l=['a','b','c']
bm=dict.fromkeys(l,['-1','-1'])
u={'a':['Q','P']}
bm.update(u)
bm
# {'a': ['Q', 'P'], 'c': ['-1', '-1'], 'b': ['-1', '-1']}
for k in bm.keys():
    bm[k].append('DDD')
bm
# {'a': ['Q', 'P', 'DDD'], 'c': ['-1', '-1', 'DDD', 'DDD'], 'b': ['-1', '-1', 'DDD', 'DDD']}

I was expecting appending DDD to happen once for c and b like this:

{'a': ['Q', 'P', 'DDD'], 'c': ['-1', '-1', 'DDD'], 'b': ['-1', '-1', 'DDD']}

Upvotes: 1

Views: 48

Answers (1)

Jean-François Fabre
Jean-François Fabre

Reputation: 140178

this

bm=dict.fromkeys(l,['-1','-1'])

Is reusing the same list ['-1','-1'] for all keys, which explains the effect you're witnessing.

to achieve what you want you could do this with a dict comprehension

bm = {x:[-1,1] for x in ['a','b','c']}

(the loop within the dict comp ensures that a different instance of the [-1,1] list is created for each value, which guarantees independence)

Full example:

bm = {x:[-1,1] for x in ['a','b','c']}

u={'a':['Q','P']}
bm.update(u)
print(bm)
for k in bm.keys():
    bm[k].append('DDD')

print(bm)

result:

{'c': [-1, 1], 'a': ['Q', 'P'], 'b': [-1, 1]}
{'c': [-1, 1, 'DDD'], 'a': ['Q', 'P', 'DDD'], 'b': [-1, 1, 'DDD']}

Note: if you want that all accessed keys create a default value when not present you can use defaultdict with a lambda which creates a different instance of ['-1','-1'] every time.

from collections import defaultdict
bm = defaultdict(lambda : ['-1','-1'])

Upvotes: 1

Related Questions