簡體   English   中英

按字典最高值過濾字典列表,並考慮反轉值

[英]Filter list of dicts by highest value of dict and taking reversed values into account

假設我有如下數據:

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},
]

# there must be a better way to get max elements by reversed keys
# in list of dicts, but I think this whole another question
# so for now let this be this way. 
def get_data():
    qs_data = []
    for data in filter_data:
        for cmp_data in filter_data:
            if data['sender_id'] == cmp_data['receiver_id'] and\
                    data['receiver_id'] == cmp_data['sender_id']:
                if data['order'] > cmp_data['order']:
                    d = data
                else:
                    d = cmp_data
                if d not in qs_data:
                    qs_data.append(d)
    return qs_data

和所需的輸出將是

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

我的代碼將過濾filter_data因此我將獲得具有sender_idreceiver_id最高order值的項目列表,但對我而言receiver_id=1, sender_id=2sender_id=1, receiver_id=2

所以我的問題是還有更多的pythonic /更快的方法嗎? 或者有人可以指出改進的方向。

附注:如果有人能提出可以理解的標題,我將不勝感激。 對不起,我的英語不好。

您可以使用字典,將發送方和接收方ID的frozenset (因此順序無關緊要)映射到當前順序最高的項目。

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

然后,只需從字典中提取values()即可獲得[{'order': 3, 'receiver_id': 1, 'sender_id': 2}, {'order': 5, 'receiver_id': 2, 'sender_id': 3}]

或收集所有項目(按發送者/接收者對分組),並使用具有max的列表理解來獲得順序最高的那些:

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()]

我現在了解你嗎?

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]

創建一個空字典,它將收集新的最高字典。 我們通過你的迭代filter_data和支票金額sender_idreceiver_id ,因為你說這些的順序是無關緊要的。

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

print new.values()

例如,它將通過第一個詞典並評估其receiver_id sender_idsender_id的總和(總和為3)。 由於我們還沒有遇到sender_idreceiver_id sender_id為3的字典,因此將其添加到新字典中。

但是,下一個字典的總和為3。我們檢查其order值是否大於上一個字典。 既然如此,它將覆蓋以前的字典。

然后,我們打印我們的新字典的值,因為鍵只包含的總和sender_idreceiver_id

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM