Nested dicts in python – assigning data

Question:

I need to created dict which handle defferent settings, depends on device (this settings are covered with dicts).
For example: S1 – settings1, S2 – settings2.
Under Sx settigs i have definition about channels parameters and other things. Channels parameters here are also dicts.

Why i can’t assign dict with different lenght. It is hard to explain that with words, but looking into below code it should be clear what i want to achive:

main = ['S1', 'S2']
my_dict = dict.fromkeys(main, {})

CHANNELS_S1 = {'CH1': {'Unit': 'A', 'RANGE': '0.2'},
               'CH2': {'Unit': 'B', 'RANGE': '0.3'},
               'CH3': {'Unit': 'C', 'RANGE': '0.4'}}

CHANNELS_S2 = {'CH1': {'Unit': 'X', 'RANGE': '.2'}}


my_dict['S1']['CHANNELS'] = CHANNELS_S1
my_dict['S2']['CHANNELS'] = CHANNELS_S2

after running this i receiving:

{'S1': {'CHANNELS': {'CH1': {'Unit': 'X', 'RANGE': '.2'}}},
 'S2': {'CHANNELS': {'CH1': {'Unit': 'X', 'RANGE': '.2'}}}}

but i want to receive this:

{'S1': {'CHANNELS': {'CH1': {'Unit': 'A', 'RANGE': '0.2'},
                     'CH2: {'Unit': 'B', 'RANGE': '0.3'},
                     'CH3': {'Unit': 'C', 'RANGE': '0.4'}}},
 'S2': {'CHANNELS': {'CH1': {'Unit': 'X', 'RANGE': '.2'}}}}
Asked By: marekp3

||

Answers:

Your default dict is shared:

my_dict = dict.fromkeys(main, {})

>>> id(my_dict['S1'])
139825319264128

>>> id(my_dict['S2'])
139825319264128

So each time you modify one the other is modified because this is the same memory location.

You can use a dict comprehension:

my_dict = {x: {} for x in main}

my_dict['S1']['CHANNELS'] = CHANNELS_S1
my_dict['S2']['CHANNELS'] = CHANNELS_S2

>>> my_dict
{'S1': {'CHANNELS': {'CH1': {'Unit': 'A', 'RANGE': '0.2'},
   'CH2': {'Unit': 'B', 'RANGE': '0.3'},
   'CH3': {'Unit': 'C', 'RANGE': '0.4'}}},
 'S2': {'CHANNELS': {'CH1': {'Unit': 'X', 'RANGE': '.2'}}}}

From the documentation

fromkeys() is a class method that returns a new dictionary. value defaults to None. All of the values refer to just a single instance, so it generally doesn’t make sense for value to be a mutable object such as an empty list. To get distinct values, use a dict comprehension instead.

Answered By: Corralien
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.