Skip to content Skip to sidebar Skip to footer

Filter List Of Dicts By Highest Value Of Dict And Taking Reversed Values Into Account

Let's say i have data looking like this: filter_data = [ {'sender_id': 1, 'receiver_id': 2, 'order': 1}, {'sender_id': 2, 'receiver_id': 1, 'order': 3}, {'sender_id': 3

Solution 1:

You can use a dictionary, mapping a frozenset of sender and receiver ID (so order does not matter) to the item with the currently highest order.

result = {}
for item in filter_data:
    key = frozenset([item["sender_id"], item["receiver_id"]])
    if key not in result or result[key]["order"] < item["order"]:
        result[key] = item

Then, just extract the values() from the dictionary to get [{'order': 3, 'receiver_id': 1, 'sender_id': 2}, {'order': 5, 'receiver_id': 2, 'sender_id': 3}]

Or collect all the items, grouped by sender/receiver pair, and use a list comprehension with max to get those with the highest orders:

result = collections.defaultdict(list)
for item in filter_data:
    key = frozenset([item["sender_id"], item["receiver_id"]])
    result[key].append(item)
max_values = [max(lst, key=lambda x: x["order"]) for lst in result.values()]

Solution 2:

Did I understand you now?

from itertools import groupby

grp = groupby(filter_data, lambda x: (min(x["sender_id"], x["receiver_id"]), max(x["sender_id"], x["receiver_id"])))
l = [sorted(g, key = lambda x: -x["order"])[0] for k, g in grp]

Solution 3:

Create an empty dictionary that will gather the new highest dictionary. We iterate through your filter_data and check the sum of sender_id and receiver_id, since you said that the order of those was irrelevant.

filter_data = [
    {'sender_id': 1, 'receiver_id': 2, 'order': 1},
    {'sender_id': 2, 'receiver_id': 1, 'order': 3},
    {'sender_id': 3, 'receiver_id': 2, 'order': 5},
    {'sender_id': 2, 'receiver_id': 3, 'order': 2},
]

new = {}
for d in filter_data:
    total = d['sender_id'] + d['receiver_id']
    if total in new:
        if d['order'] > new[total]['order']:
            new[total] = d
    else:
        new[total] = d

printnew.values()

For example, it will go through the first dictionary and evaluate the sum of its receiver_id and sender_id (The sum is 3). Since we have not encountered a dictionary that has sender_id and receiver_id adding up to 3 yet, it is added to our new dictionary.

However, the next dictionary also has a sum of 3. We check to see if its order value is greater than the previous dictionary. Since it is, it overrides that former dictionary.

Then we print the values of our new dictionary since the keys only contain the sum of sender_id and receiver_id.

Post a Comment for "Filter List Of Dicts By Highest Value Of Dict And Taking Reversed Values Into Account"