Pines
Pines

Reputation: 47

python dictionary of dictionaries comprehension with nested loops

I am starting to understand and implement dictionary comperhension. I am trying to build a dictionary with nested dictionaries like this:

{serviceA:{ip_server1: flag, ip_server2:flag...}, serviceB{ip_server1: flag, ip_server_2: flag...etc}}

I am having problems to build it as when getting the result It just throws me tha last element. I have tried many ways and all lead the same way. Here is the code I used :

DICTIONARY 1:

services_dict = {key_service: value for key_service,value in config_file.iteritems() if key_service.startswith("s-")}
#It returns a dictionary in this form {service1: [list_of_flags]}

Then I have an external list that has the server IPs

server_list = [S1, S2, S3, S4..etc]

After this I want to use dic comprehension to build the complete dictionary:

new_services_dict = { key1: {key2:fl} for key1, flag_list in corrected_dict.items() for key2, fl in zip(server_list, flag_list)}

The problem is that it only returns the last element of the ip list (1 element only)

{'ServiceA': {'last_server_ip_in_list': 'Last_flag_in_list'}}

I am not sure why it is not appending new values and just take sthe last item in the iteration.

Any help would be greatly appreciated. I have already tried many ways and i am not able to find out which part of the iteraiton i am missing.

UPDATED INFO

As requested in the coment below here is some sample data to clarify the question: Let say we have to map a list of students that I have separated from a dictionary that contains the college subjects with the grades:

services_dict = {math:['A','B','C','D'], Databases:['B','C','D', 'A']} students list = ['Jhon','Michael','Leslie','Lorraine']

The grades are listed respectively from the student list, so that is not the problem (on which grade belongs to whom).

What is intended it to get a dictionary in the form:

{'math':{'Jhon':'A', 'Michael':'B', 'Leslie':'C', 'Lorraine':'D'}, Databases:{'Jhon':'B', 'Michael':'C', 'Leslie':'D', 'Lorraine':'A'}}

The problem i am getting is that new_services_dict is only returning:

{'math:{'Lorraine':'D'}

I hope this is clearer than the explanation above.

Upvotes: 0

Views: 245

Answers (1)

LMc
LMc

Reputation: 18642

Well for starters, it looks like all the keys in new_services_dict will be the same since you have a nested for loop and not a nested dictionary comprehension, which I am assuming is what you want.

For example,

>>>{k1:{k2:v} for k1 in ['a','b'] for k2,v in zip(['aa','bb'],[1,2])}
{'b': {'bb': 2}, 'a': {'bb': 2}} # dictionaries are unordered

Here k1 takes value of 'a' then pauses until k2,v for loop iterates through all of the items before resuming. This just keeps reassigning k1 to {'bb':2} since that's the last item in the k2 iteration. This is why all of your values are probably coming out the same.

What you probably want is a nested dictionary comprehension that would look like this:

>>>{k1:{k2:v for k2,v in zip(['aa','bb'],[1,2])} for k1 in ['a','b']}
{'b': {'aa': 1, 'bb': 2}, 'a': {'aa': 1, 'bb': 2}}

Here, k1 takes the value of 'a' then pauses until the nested comprehension runs.

Check this out for more information and better explanation on nested comprehensions. This is for list comprehensions, but the same logic applies.

Upvotes: 1

Related Questions