CrazyIntent
CrazyIntent

Reputation: 41

How do you update nested dictionaries in python with overlapping keys?

I only want to update 1 dictionary value in a dictionary, but it seems to update the union of 2 keys:

Y = dict(zip(['A', 'B'], [dict.fromkeys(range(2010,2014), [])] * 2))
zz = {'A':{2012: [(666,999)], 2013: []}, 'B':{2010:[], 2011:[(666,999)]}}

Y['A'][2012] = zz['A'][2012]

Result:

{'A': {2010: [], 2011: [], 2012: [(666, 999)], 2013: []}, 'B': {2010: [], 2011: [], 2012: [(666, 999)], 2013: []}}

I only want to update 2012 of 'A'.

I am a beginner python programmer.

Thanks

Upvotes: 0

Views: 494

Answers (2)

sashkello
sashkello

Reputation: 17871

This:

[dict.fromkeys(range(2010,2014), [])] * 2

creates two same dictionaries, instead of two copies of identical dictionary. So, Y['A'][2012] is the same thing as Y['B'][2012].

You can fix it by doing:

y = dict(zip(['A', 'B'], [dict.fromkeys(range(2010,2014), []) for _ in [_,_]]))

Related:

List of lists changes reflected across sublists unexpectedly

Generating sublists using multiplication ( * ) unexpected behavior

Nested List Indices

Upvotes: 0

user2357112
user2357112

Reputation: 280291

This part:

[dict.fromkeys(range(2010,2014), [])] * 2

creates a list where both elements are the same dict object. Furthermore, in that single dict, all 4 values are the same list object.

This part:

Y['A'][2012] = zz['A'][2012]

takes the list object stored in zz['A'][2012] and makes Y['A'][2012] also refer to that list.

You could make independent dicts with independent lists by doing the following:

Y = {key1: {key2: [] for key2 in range(2010, 2014)} for key1 in ['A', 'B']}

As I'm not sure what you're trying to do with Y['A'][2012] = zz['A'][2012], I can't offer a solution there.

Upvotes: 2

Related Questions