views:

57

answers:

2

I have a dictionary, with 300 key value pairs, where each of the keys are integers and the values are dictionaries with three key value pairs. The inner dictionaries all have the same keys, but different values. The whole thing looks pretty much like this:

nested_dicts = 
{1: {'name1':88.4,
     'name2':22.1,
     'name3':115.7},
2:  {'name1':89.4,
     'name2':23.7,
     'name3':117.9}
...
300:{'name1':110.1,
     'name2':36.6,
     'name3':122.4}
 }

If it's not clear from the above example of the data structure, this nested dictionary should probably look like this:

better_dict = 
{'name1': [88.4, 89.4, ..., 110.1],
 'name2': [22.1, 23.7, ..., 36.6],
 'name3': [115.7, 117.9, ..., 122.4]}

So, I'd like to do a transformation from nested_dicts to better_dict.

I'm having trouble pulling this off. I've gotten close, but my trouble comes from trying to figure out how to make sure that the resulting lists are in the correct order. That is, the order of the values in the list should correspond to the keys in the outer dictionary of the original nested_dict. Also, my code uses for loops, but I feel like this is a natural application of generators/list comprehensions. Any help would be appreciated.

+3  A: 

After adjusting your input dict to be:

>>> nested_dicts
{0: {'name2': 22.1, 'name3': 115.7, 'name1': 88.4},
 1: {'name2': 23.7, 'name3': 117.9, 'name1': 89.4},
 2: {'name2': 36.6, 'name3': 122.4, 'name1': 110.1}}
>>> for i in sorted(nested_dicts):
    for k, v in nested_dicts[i].items():
        if k not in n:
            n[k] = [None] * len(nested_dicts)
        n[k][i] = v

>>> n
defaultdict(<class 'list'>, {'name2': [22.1, 23.7, 36.6],
 'name3': [115.7, 117.9, 122.4], 'name1': [88.4, 89.4, 110.1]})

I have to note that your original structure just needs to be a list of dicts, given restrictions on keys.

ETA: your request to preserve key order would necessitate proper indexes in your original nested_dict. That is there needs to be a continuous sequence starting from 0.

SilentGhost
You still have to sort the dictionary to append the elements in the right order. Otherwise the order is not guaranteed to be stable.
Felix Kling
Yeah, this is pretty much the code I have thus far (although defaultdict is a good call). I guess I didn't make it clear enough that the order of the values in the list matters. It should correspond to the keys in the outer dictionary of the original nested_dict. This is where my trouble comes from.
Wilduck
Having key order from 0 would be fairly easy to do. I was just having trouble getting the sorting to happen in the right place.
Wilduck
+3  A: 

In python2.7+

{n:[nested_dicts[i][n] for i in range(1,301)] for n in ["name1","name2","name3"]}

for python2.6

dict((n, [nested_dicts[i][n] for i in range(1,301)]) for n in ["name1","name2","name3"])

note that the positions in your lists are indexed from 0, not 1

gnibbler
This works very nicely. In my previous attempts to use generators/list comprehensions I hadn't thought to just drop a list of the names into the generator, making things quite difficult for myself. Thank you.
Wilduck