Create a dictionary from multiple lists, one list as key, other as value

Lets say I have these lists:

key_list = [key1, key2,.....,key20]
val_list = [[val1, val2,...,val20],[val1, val2,...,val20], [val1, val2,...,val20],....,[val1, val2,...,val20]]

How can I make it so that I can use the first list as keys and then iterate through each list in the second list and make a dictionary like this:

{
    "rows": [
    {
        "key1": "val1",
        "key2": "val2",
         .
         .
         .
        "key20": "val20"
    },
    {
        "key1": "val1",
        "key2": "val2",
         .
         .
         .
        "key20": "val20"
    },
    {
        "key1": "val1",
        "key2": "val2",
         .
         .
         .
        "key20": "val20"
    },
    
    {
        "key1": "val1",
        "key2": "val2",
         .
         .
         .
        "key20": "val20"
    },
    .
    .
    .
    {
        "key1": "val1",
        "key2": "val2",
         .
         .
         .
        "key20": "val20"
    }
    
    ]
}

I tried this one but it is not giving me the desired output:

data = []
for row in val_list:
  t = dict.fromkeys(key_list, row)
  data.append(t)
print(json.dumps(data, indent=4))

>Solution :

Use the zip() function to combine a list of keys with corresponding values, then pass the resulting iterator of (key, value) combinations to dict():

data = {"rows": [dict(zip(key_list, row)) for row in val_list]}

This works because zip(iter1, iter2) pairs up each element from iter1 with those of iter2, and the dict() constructor accepts an iterator of 2-value tuples:

Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value.

In my example above I used a list comprehension to generate the whole output list in a single expression:

>>> key_list = ['key1', 'key2', 'key3']
>>> val_list = [['v0_1', 'v0_2', 'v0_3'], ['v1_1', 'v1_2', 'v1_3'], ['v2_1', 'v2_2', 'v2_3']]
>>> {"rows": [dict(zip(key_list, row)) for row in val_list]}
{'rows': [{'key1': 'v0_1', 'key2': 'v0_2', 'key3': 'v0_3'}, {'key1': 'v1_1', 'key2': 'v1_2', 'key3': 'v1_3'}, {'key1': 'v2_1', 'key2': 'v2_2', 'key3': 'v2_3'}]}
>>> from pprint import pp
>>> pp({"rows": [dict(zip(key_list, row)) for row in val_list]})
{'rows': [{'key1': 'v0_1', 'key2': 'v0_2', 'key3': 'v0_3'},
          {'key1': 'v1_1', 'key2': 'v1_2', 'key3': 'v1_3'},
          {'key1': 'v2_1', 'key2': 'v2_2', 'key3': 'v2_3'}]}

dict.fromkeys() is the wrong tool here as it reuses the second argument for each of the keys.

Leave a Reply