Skip to content Skip to sidebar Skip to footer

'zip' Dictionary Of Lists In Python

I have a dictionary of lists, and I want to merge them into a single list of namedtuples. I want the first element of all the lists in the first tuple, the second in the second and

Solution 1:

>>> d = {'key1': [1, 2, 3], 'key2': [4, 5, 6], 'key3': [7, 8, 9]}
>>> keys = d.keys()
>>> [dict(zip(keys, vals)) for vals inzip(*(d[k] for k in keys))]
[{'key3': 7, 'key2': 4, 'key1': 1},
 {'key3': 8, 'key2': 5, 'key1': 2},
 {'key3': 9, 'key2': 6, 'key1': 3}]

Solution 2:

First get the keys. You could sort them or whatever you like at this stage. Maybe you know what keys to use in what order, so you don't need to examine the data.

keys = list(d.keys())

Define the named tuple:

Record = collections.namedtuple('Record', keys)

Iterate all the lists in parallel:

[Record(*t) fortinzip(*(d[k] forkin keys))]

or list(map(Record, *(d[k] for k in keys))) if you like map.

Note that if keys is just list(d.keys()) then you can use d.values() in place of (d[k] for k in keys), because even though the order of keys in the dictionary is arbitrary it's guaranteed to be the same as the order of values. So if you don't care about the order of the fields in the namedtuple then it simplifies to:

Record = collections.namedtuple('Record', d.keys())
[Record(*t) for t in zip(*(d.values()))]

or list(map(Record, *d.values())) if you like map.

Solution 3:

Based on Chaudhary's answer, I developed a generator-based solution. This might be helpful when the dict is huge.

defzip_dict(d):
    for vals inzip(*(d.values())):
        yielddict(zip(d.keys(), vals))

Example usage:

d = dict(
    x=[1,3,5,7,9],
    y=[2,4,6,8,10]
)

for t in zip_dict(d):
    print(t)

The result would be:

{'x': 1, 'y': 2}
{'x': 3, 'y': 4}
{'x': 5, 'y': 6}
{'x': 7, 'y': 8}
{'x': 9, 'y': 10}

Post a Comment for "'zip' Dictionary Of Lists In Python"