4

I've a list with master keys and a list of list of lists, where the first value of each enclosed list (like 'key_01') shall be a sub key for the corresponding values (like 'val_01', 'val_02'). The data is shown here:

master_keys = ["Master_01", "Master_02", "Master_03"]
data_long = [[['key_01','val_01','val_02'],['key_02','val_03','val_04'], ['key_03','val_05','val_06']],
           [['key_04','val_07','val_08'], ['key_05','val_09','val_10'], ['key_06','val_11','val_12']],
           [['key_07','val_13','val_14'], ['key_08','val_15','val_16'], ['key_09','val_17','val_18']]]

I would like these lists to be combined into a dictionary of dictionaries, like this:

master_dic = {
"Master_01": {'key_01':['val_01','val_02'],'key_02': ['val_03','val_04'], 'key_03': ['val_05','val_06']}, 
"Master_02": {'key_04': ['val_07','val_08'], 'key_05': ['val_09','val_10'], 'key_06': ['val_11','val_12']}, 
"Master_03": {'key_07': ['val_13','val_14'], ['key_08': ['val_15','val_16'], 'key_09': ['val_17','val_18']}
}

What I've got so far is the sub dict:

import itertools

master_dic = {}
servant_dic = {}
keys = []
values = []
for line in data_long:
    for item in line:
        keys.extend(item[:1])
        values.append(item[1:])
servant_dic = dict(itertools.izip(keys, values))

Which puts out a dictionary, as expected.

servant_dic = {
'key_06': ['val_11','val_12'], 'key_04': ['val_08','val_07'], 'key_05': ['val_09','val_10'], 
'key_02': ['val_03','val_04'], 'key_03': ['val_05','val_06'], 'key_01': ['val_01','val_02']
 }

The problem is, that if I want to add the master_keys to this dictionary, so I get the wanted result, I'd have to do this in a certain order, which would be possible, if each line had a counter like this:

enumerated_dic =
{
0: {'key_01':['val_01','val_02'],'key_02': ['val_03','val_04'], 'key_03': ['val_05','val_06']}, 
1: {'key_04': ['val_07','val_08'], 'key_05': ['val_09','val_10'], 'key_06': ['val_11','val_12']}, 
2: {'key_07': ['val_13','val_14'], ['key_08': ['val_15','val_16'], 'key_09': ['val_17','val_18']}
}

I'd love to do this with enumerate(), while each line of the servant_dic is build, but can't figure out how. Since afterwards, i could simply replace the counters 0, 1, 2 etc. with the master_keys.

Thanks for your help.

Mauro Baraldi
  • 6,346
  • 2
  • 32
  • 43
MrPadlog
  • 115
  • 1
  • 8

4 Answers4

6
master_keys = ["Master_01", "Master_02", "Master_03"]
data_long = [[['key_01','val_01','val_02'],['key_02','val_03','val_04'], ['key_03','val_05','val_06']],
           [['key_04','val_07','val_08'], ['key_05','val_09','val_10'], ['key_06','val_11','val_12']],
           [['key_07','val_13','val_14'], ['key_08','val_15','val_16'], ['key_09','val_17','val_18']]]


_dict = {}

for master_key, item in zip(master_keys, data_long):
    _dict[master_key] = {x[0]: x[1:] for x in item}

print _dict
turkus
  • 4,637
  • 2
  • 24
  • 28
  • After reading up on `zip()` (again), it dawned on me. @turkus and @ig-melnyk, your approach really taught me, what I wanted to learn here, thanks! @mpiskore, the approach using `.pop()`, to me, is a very creative one. I do like it. – MrPadlog Sep 01 '16 at 09:16
2

Hope this will help:

{master_key: {i[0]: i[1:] for i in subkeys} for master_key, subkeys in zip(master_keys, data_long)}
ig-melnyk
  • 2,769
  • 2
  • 25
  • 35
1

You can also use pop and a dict comprehension:

for key, elements in zip(master_keys, data_long):
    print {key: {el.pop(0): el for el in elements}}
   ...:
{'Master_01': {'key_02': ['val_03', 'val_04'], 'key_03': ['val_05', 'val_06']}}
{'Master_02': {'key_06': ['val_11', 'val_12'], 'key_04': ['val_07', 'val_08'], 'key_05': ['val_09', 'val_10']}}
{'Master_03': {'key_07': ['val_13', 'val_14'], 'key_08': ['val_15', 'val_16'], 'key_09': ['val_17', 'val_18']}}
nalzok
  • 14,965
  • 21
  • 72
  • 139
mpiskore
  • 671
  • 8
  • 18
1

My functional approach:

master_dic = dict(zip(master_keys, [{k[0]: k[1::] for k in emb_list} for emb_list in data_long]))
print(master_dic)
Etaoin
  • 149
  • 2
  • 7