I have a list of dictionaries
lst = [{'a': (1, 2, 3), 'b': (2, 3)},
{'c': (3, 6), 'd': (4, 8), 'e': (5, 10)},
{'d': (6, 12), 'e': (7, 14)}]
For each key in each dictionary, I want to keep only the first element of the values. So the desired output is
[{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}, {'d': 6, 'e': 7}]
I can get it using a list comprehension like
[{key: val[0] for key, val in dct.items()} for dct in lst]
However, I want to know if it's possible to get the same output using map, itemgetter, itertools, functools etc. What I have so far:
map(dict.values, lst)
But I don't know how to go from here.
For nested iterations, I don't think we can do it without the help of lambda expressions:
from operator import itemgetter, methodcaller
list(map(
lambda items: dict(zip(
map(itemgetter(0), items),
map(itemgetter(0), map(itemgetter(1), items))
)), map(methodcaller('items'), lst)))
# [{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}, {'d': 6, 'e': 7}]
I have to say it's very ugly.
Update: I found a way to avoid lambda:
func = lambda d: dict(zip(d, map(itemgetter(0), d.values())))
map(func, lst)
dict
can be moved outside lambda. We just need to add another map
:func = lambda d: zip(d, map(itemgetter(0), d.values()))
map(dict, map(func, lst))
zip
outside lambda:func = lambda d: map(itemgetter(0), d.values())
map(dict, map(zip, lst, map(func, lst)))
d.values
outside lambda. Here, since the element type of the list is determined, we directly use dict.values
instead of operator.methodcaller
:func = lambda values: map(itemgetter(0), values)
map(dict, map(zip, lst, map(func, map(dict.values, lst))))
functools.partial
:map(dict, map(zip, lst, map(partial(map, itemgetter(0)), map(dict.values, lst))))
Test:
>>> from operator import itemgetter
>>> from functools import partial
>>> lst = [{'a': (1, 2, 3), 'b': (2, 3)},
... {'c': (3, 6), 'd': (4, 8), 'e': (5, 10)},
... {'d': (6, 12), 'e': (7, 14)}]
>>> map(dict, map(zip, lst, map(partial(map, itemgetter(0)), map(dict.values, lst))))
<map object at 0x000002A0542CBB20>
>>> list(_)
[{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}, {'d': 6, 'e': 7}]