How to create nested and complex dictionary from an existing one?

Question:

I’d like to create a new dictionary from this dictionary:

inp = {'tagA': 
     {'2023-03-09 00:00:00': 'X', 
      '2023-03-09 01:00:00': 'X', 
      '2023-03-09 02:00:00': 'Y', 
      '2023-03-09 03:00:00': 'Z', 
      '2023-03-09 04:00:00': 'X'}, 
      'tagB': 
      {'2023-03-09 00:00:00': 'Y', 
       '2023-03-09 01:00:00': 'X', 
       '2023-03-09 02:00:00': 'X', 
       '2023-03-09 03:00:00': 'Y', 
       '2023-03-09 04:00:00': 'Z'}}

The desired output is:

output = {
    'tags':[
    {
        'name': 'tagA',
        'values':[
    {
        'timestamp':'2023-03-09 00:00:00',
        'value':'X'
    },
    {
        'timestamp':'2023-03-09 01:00:00',
        'value':'X'
    },
    {
        'timestamp':'2023-03-09 02:00:00',
        'value':'Y'
    },
    {
        'timestamp':'2023-03-09 03:00:00',
        'value':'Z'
    },
    {
        'timestamp':'2023-03-09 04:00:00',
        'value':'X'
    }
    ]
    },
    {
        'name': 'tagB',
        'values':[
...]}]}

I wrote a for loop to iterate through each values of the inner list but with this logic all the values will be assigned to all the keys.

inner_list = []
outer_dict = {}
outer_list = []

for k, v in inp.items():
    print(k)

    for timestamp, value in v.items():
        inner_list.append({'timestamp':timestamp, 'value':value})
        outer_list.append({'name': k, 'values':inner_list})
        outer_dict.update({'tags': outer_list})

How can I fix this?

Asked By: Nili

||

Answers:

Here the basic idea is to loop over by levels, like below first I went to tagA and in used second to go through the values and assign as list to main tag.

Code:

dic = {'tags': []}

for name, values in inp.items():
    main = {'name': name, 'values': []}
    for time, val in values.items():
        main['values'].append({'timestamp': time, 'value': val})
    dic['tags'].append(main)

dic

Output:

{'tags': [{'name': 'tagA',
   'values': [{'timestamp': '2023-03-09 00:00:00', 'value': 'X'},
    {'timestamp': '2023-03-09 01:00:00', 'value': 'X'},
    {'timestamp': '2023-03-09 02:00:00', 'value': 'Y'},
    {'timestamp': '2023-03-09 03:00:00', 'value': 'Z'},
    {'timestamp': '2023-03-09 04:00:00', 'value': 'X'}]},
  {'name': 'tagB',
   'values': [{'timestamp': '2023-03-09 00:00:00', 'value': 'Y'},
    {'timestamp': '2023-03-09 01:00:00', 'value': 'X'},
    {'timestamp': '2023-03-09 02:00:00', 'value': 'X'},
    {'timestamp': '2023-03-09 03:00:00', 'value': 'Y'},
    {'timestamp': '2023-03-09 04:00:00', 'value': 'Z'}]}]}
Answered By: R. Baraiya
output = {}
output['tags'] = []
for key, value in inp.items():
    tag = {}
    tag['name'] = key
    tag['values'] = []
    for timestamp, val in value.items():
        tag['values'].append({'timestamp': timestamp, 'value': val})
    output['tags'].append(tag)

Answered By: Shekhrox

This looks like a good use case for comprehensions:

result = {
    "tags": [
        {"name": tag,
         "values": [{"timestamp": ts, "value": v} for ts, v in values.items()]}
        for tag, values in inp.items()
    ]
}

Result for the sample:

{'tags': [{'name': 'tagA',
           'values': [{'timestamp': '2023-03-09 00:00:00', 'value': 'X'},
                      {'timestamp': '2023-03-09 01:00:00', 'value': 'X'},
                      {'timestamp': '2023-03-09 02:00:00', 'value': 'Y'},
                      {'timestamp': '2023-03-09 03:00:00', 'value': 'Z'},
                      {'timestamp': '2023-03-09 04:00:00', 'value': 'X'}]},
          {'name': 'tagB',
           'values': [{'timestamp': '2023-03-09 00:00:00', 'value': 'Y'},
                      {'timestamp': '2023-03-09 01:00:00', 'value': 'X'},
                      {'timestamp': '2023-03-09 02:00:00', 'value': 'X'},
                      {'timestamp': '2023-03-09 03:00:00', 'value': 'Y'},
                      {'timestamp': '2023-03-09 04:00:00', 'value': 'Z'}]}]}
Answered By: Timus
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.