how to form a dictionary by combining two list

Viewed 133

i have the following issue i have two list need to form a dictionary

header=["a","b","c"]
list=[1,2,4,5,7,9,6,5,1,5,8,12]

This is how i want the result to look like

{
  outer1:{
    inner1:{
      "a":1,
      "b":2,
      "c":4,
    },
    inner2:{
      "a":5,
      "b":7,
      "c":9,
    },
    }
  outer2:{
     inner1:{
      "a":6,
      "b":5,
      "c":1,
    },
    inner2:{
      "a":5,
      "b":8,
      "c":12,
    },

  }
}

i will appreciate your help incase anything needs clarification kindly comment

below is how i tried to solve the issue

dictionary = {"outer" + str(h+1): {"inner" + str(i): {
            header[j]: list[h*len(header)+j] for j in range(len(header))} for i in
            range(3)} for h
            in range(len(list) // len(header))}
4 Answers

This will create a dictionary as you want it to be:

header_raw=["a","b","c"]
li=[1,2,4,5,7,9,6,5,1,5,8,12]

header=header_raw*int(len(li) / len(header_raw))

len_r = len(header_raw)
iterations = int(len(li)/len(header_raw))
ind2_iterations = int(iterations/2)

{f"outer {index}": {f"inner {ind2}": {header[i+index*len_r]:li[i+(((index*2)+ind2)*len_r)] for i in range(len_r)} for ind2 in range(0,ind2_iterations)} for index in range(0,ind2_iterations)}

First make both lists the same size. Then create some helper variables, that help you to iterate through the dict of depth 3. It would look nicer without dict comprehention, but it might help you out.

Here's an itertools based one. You'd only need to parameterise it based on the criteria you're following to structure the output dictionary, that is, the amount of iterations of the outer and inner loops:

from itertools import islice, repeat

header=["a","b","c"]
l=iter([1,2,4,5,7,9,6,5,1,5,8,12])

d = {}
for i in range(2):
    d_temp = {}
    for j, head in enumerate(repeat(header,2)):
        d_temp[f'inner{j}'] = dict(zip(head,islice(l,0,3)))
    d[f'outer{i}'] = d_temp

print(d)

{'outer0': {'inner0': {'a': 1, 'b': 2, 'c': 4},
            'inner1': {'a': 5, 'b': 7, 'c': 9}},
 'outer1': {'inner0': {'a': 6, 'b': 5, 'c': 1},
            'inner1': {'a': 5, 'b': 8, 'c': 12}}}

A solution that scales for any number of headers, values and outer dicts.

  • generate_inner_dicts takes a list of headers and a generator of values, consuming (up to) the count of headers values from the values and zips them up into dicts e.g. {'a': 1, 'b': 2, 'c': 4} until it's run out of values
  • generate_nested_dicts takes that generator and nests them into the structure required, until it runs out of content in the inner_dict_generator.
from itertools import count


def generate_inner_dicts(header, values):
    values = iter(values)
    while True:
        inner = dict(zip(header, values))
        if not inner:
            break
        yield inner


def generate_nested_dicts(inner_dict_generator):
    root = {}
    try:
        for outer_count in count(1):
            for inner_count in range(10, 60, 5):
                inner_dict = next(inner_dict_generator)
                outer = root.setdefault(f"outer{outer_count}", {})
                outer[f"inner{inner_count}"] = inner_dict
    except StopIteration:  # Ran out of inner dicts
        pass
    return root


header = [f"f{i}" for i in range(1, 30)]
values = list(range(1, 4061))

nd = generate_nested_dicts(generate_inner_dicts(header, values))

print(nd)

You may have to complete the code if you want to consider more cases, but here is an idea:

header=["a","b","c"]
my_list=[1,2,4,5,7,9,6,5,1,5,8,12]

dic = {}

for i in range(int(len(my_list)/6)):
    sublist = my_list[:6]
    my_list = my_list[6:]
    
    d1 = {"a":sublist[0], "b":sublist[1], "c":sublist[2]}
    d2 = {"a":sublist[3], "b":sublist[4], "c":sublist[5]}
    
    dic["outer"+str(i+1)] = {"inner1":d1, "inner2":d2}

print(dic)
Related