[英]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_id
和receiver_id
最高order
值的項目列表,但對我而言receiver_id=1, sender_id=2
與sender_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_id
和receiver_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_id
和sender_id
的總和(總和為3)。 由於我們還沒有遇到sender_id
和receiver_id
sender_id
為3的字典,因此將其添加到新字典中。
但是,下一個字典的總和為3。我們檢查其order
值是否大於上一個字典。 既然如此,它將覆蓋以前的字典。
然后,我們打印我們的新字典的值,因為鍵只包含的總和sender_id
和receiver_id
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.