Home > Software design >  How to split a list of dicts by key
How to split a list of dicts by key

Time:10-27

I have the following list of dicts:

list_of_dicts = [
    {"type": "X", "hour": 22},
    {"type": "A", "measure": "1"},
    {"type": "B", "measure": "2"},
    {"type": "X", "hour": 23},
    {"type": "A", "measure": "3"},
    {"type": "X", "hour": 24},
    {"type": "A", "measure": "4"},
    {"type": "B", "measure": "5"},
    {"type": "C", "measure": "6"}
]

How can I split it into a dict where keys are the 'hour' values from 'type' = 'X' dicts and values are the other dicts between two 'type' = 'X' dicts? That's what I want to obtain using this example, but the interval between two 'type' = 'X' dicts can be variable.

dict_of_dicts = {
    22: [
        {"type": "A", "measure": "1"},
        {"type": "B", "measure": "2"},
    ],
    23:[
        {"type": "A", "measure": "3"}
    ],
    24:[
        {"type": "A", "measure": "4"},
        {"type": "B", "measure": "5"},
        {"type": "C", "measure": "6"},
    ]
}

Thanks in advance!

CodePudding user response:

This code should do the trick.
It creates new elements in a result dictionary, every time it comes across a dictionary which contains the "hour" key.

res = {}
cur_key = None

for d in list_of_dicts:
    if "hour" in d:
        cur_key = d["hour"]
        res[cur_key] = []
    elif cur_key is not None:
        res[cur_key].append(d)

CodePudding user response:

Here is another approach using list comprehension and a neat little trick (borrowed from here) to make a while loop work inside it:

list_of_dicts = [
    {"type": "X", "hour": 22},
    {"type": "A", "measure": "1"},
    {"type": "B", "measure": "2"},
    {"type": "X", "hour": 23},
    {"type": "A", "measure": "3"},
    {"type": "X", "hour": 24},
    {"type": "A", "measure": "4"},
    {"type": "B", "measure": "5"},
    {"type": "C", "measure": "6"}
]

def while_generator(lst):
    i = 0
    while i < len(lst) and lst[i]['type'] != 'X':
        yield lst[i]
        i  = 1

dict_of_dicts = {
    d['hour']: [e for e in while_generator(list_of_dicts[i 1:])]
    for i, d in enumerate(list_of_dicts) if d['type'] == 'X'
}

print(dict_of_dicts)

Prints:

{
    22: [
        {'type': 'A', 'measure': '1'}, 
        {'type': 'B', 'measure': '2'}
    ], 
    23: [
        {'type': 'A', 'measure': '3'}
    ], 
    24: [
        {'type': 'A', 'measure': '4'}, 
        {'type': 'B', 'measure': '5'}, 
        {'type': 'C', 'measure': '6'}
    ]
}
  • Related