'Merge data from list of dict

I think what I want to do is easy but I don't know the correct way to do this.

I have a list as:

[
        {
            "id": 16,
            "condition": true,
            "tags": 6,
        },
        {
            "id": 16,
            "condition": true,
            "tags": 1,
        },
        {
            "id": 16,
            "condition": true,
            "tags": 4,
        },
        {
            "id": 3,
            "condition": false,
            "tags": 3,
        }
    ]

And I want to group the element of by list by id and condition, the output would be:

[
        {
            "id": 16,
            "condition": true,
            "tags": [6, 1, 4],
        },
        {
            "id": 16,
            "condition": false,
            "tags": [3],
        }
    ]

I can do this by looping on my list and creating another array but I was wondering about a better way to do this.

for now my code is like this:

def format(self):
    list_assigned = the_list_I_want_to_modify
    res = []
    for x in list_assigned:
        exists = [v for v in res if
                             v['id'] == x['id'] and v['condition'] == x['condition']]
        if not exists:
            x['tags'] = [x['tags']]
            res.append(x)
        else:
            exists[0]['tags'].append(x['tags'])
    return res

Thanks



Solution 1:[1]

There might be a prettier solution, but you could solve it by first creating a temporary dictionary with keys being tuples containing all the keys from your original list that are required to group by, and appending the tags in a list - I use the .setdefault(key, type) dictionary function to make a dictionary with default list elements.

Then you can unpack that dictionary into a list again afterwards with a list comprehension.

a = [
        {
            "id": 16,
            "condition": True,
            "tags": 6,
        },
        {
            "id": 16,
            "condition": True,
            "tags": 1,
        },
        {
            "id": 16,
            "condition": True,
            "tags": 4,
        },
        {
            "verified_by": 3,
            "condition": False,
            "tags": 3,
        }
    ]

tmp = {}
for elem in a:
    groupby_keys = tuple(sorted((k, v) for k, v in elem.items() if k != 'tags'))
    tmp.setdefault(groupby_keys, []).append(elem['tags'])
out = [{a[0]: a[1] for a in list(k) + [('tags', v)]} for k, v in tmp.items()]
print(out)

Output:

>>> out
[{'id': 16, 'condition': True, 'tags': [6, 1, 4]}, {'verified_by': 3, 'condition': False, 'tags': [3]}]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1