Skip to content
Advertisement

Python – Create a list of objects based on counts of another list of objects

I have a list of objects and I want to create another list of items but grouped by “Name” and two fields which are number of instances of a particular instance type. I have this :

result = [
    {"Name": "Foo", "Type": "A", "RandomColumn1": "1"},
    {"Name": "Bar", "Type": "B", "RandomColumn2": "2"},
    {"Name": "Foo", "Type": "A", "RandomColumn3": "3"},
    {"Name": "Bar", "Type": "A", "RandomColumn4": "4"},
    {"Name": "Foo", "Type": "B", "RandomColumn5": "5"},
]

I am trying to get a count of the number of different “Type” columns whilst discarding any other column – RandomColumnX in this case.

I want the above to come out like this:

[{"Name": "Foo", "A": 2, "B": 1}, {"Name": "Bar", "A": 1, "B": 1}]

I tried doing something like this :

group_requests = [{
    "Name": key,
    "A": len([d for d in list(value) if d.get('Type') == 'A']),
    "B": len([y for y in list(value) if y['Type'] == 'B']),
} for key, value in groupby(result, key=lambda x: x['Name'])]

However, it does not count the values in the “B” column and the count for this key is always 0.

Can anybody help me?

Advertisement

Answer

Mistake 1. In order for the itertools.groupby to work your input iterable needs to already be sorted on the same key function.

result = sorted(result, key=lambda x: x["Name"])

Mistake 2. The returned group i.e value is itself an iterator, so you need to save the output in order to iterate over it multiple times.

group_requests = []
for key, value in itertools.groupby(result, key=lambda x: x["Name"]):
    value = list(value)  # save the output
    temp = {
        "Name": key,
        "A": len([d for d in value if d.get("Type") == "A"]),
        "B": len([y for y in value if y["Type"] == "B"]),
    }
    group_requests.append(temp)
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement