I am trying to aggregate lists into dict. First column can be treated as id and second column as some random element. I want all elements assigned to the same id to be grouped in a list under that id. Id=None
, empty lists need to be filtered out and not allow duplicate elements.
Probably seeing input and output will be more expressive
This is input:
[
[1, 1],
[2, 1],
[2, 2],
[2, 3],
[2, 3],
[2, 4],
[],
[None, 5]
]
This is expected output:
{
1: [1],
2: [1, 2, 3, 4]
}
I got stuck at this functional and imperative hybrid:
filtered_groups = list(filter(lambda group: len(group) == 2 and group[0] is not None, groups))
grouper = {}
for group in filtered_groups:
id = group[0]
element = group[1]
grouper_entry = grouper.get(id)
if not grouper_entry:
grouper_entry = grouper[id] = []
if element not in grouper_entry:
grouper_entry.append(element)
expected_result = {
1: [1],
2: [1, 2, 3, 4]
}
assert grouper == expected_result
How can I rewrite this for loop
into mapping/reducing/grouping function to achieve expected result?
CodePudding user response:
Try:
lst = [[1, 1], [2, 1], [2, 2], [2, 3], [2, 3], [2, 4], [], [None, 5]]
out, seen = {}, set()
for a, b in (item for item in lst if len(item) == 2 and item[0] is not None):
if (a, b) not in seen:
out.setdefault(a, []).append(b)
seen.add((a, b))
print(out)
Prints:
{1: [1], 2: [1, 2, 3, 4]}
CodePudding user response:
A solution using defaultdict
from collections import defaultdict
lst = [[1, 1], [2, 1], [2, 2], [2, 3], [2, 3], [2, 4], [], [None, 5]]
dic = defaultdict(list)
for sublist in lst:
if (len(sublist) == 2):
if sublist[0] != None:
id, val = sublist
dic[id].append(val)
print(dic)