我们说我的数据看起来像这样:
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
,因此我会获得order
和sender_id
receiver_id
值最高的项目列表,但对我来说receiver_id=1, sender_id=2
与sender_id=1, receiver_id=2
所以我的问题是有更多pythonic /更快的方法吗?或者可能有人指出改进的方向。
P.S。如果有人能提出可以理解的头衔,我将非常感激。抱歉我的英语不好。
答案 0 :(得分:1)
您可以使用字典,将frozenset
发件人和收件人ID(因此顺序无关紧要)映射到当前最高顺序的项目。
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()]
答案 1 :(得分:1)
我现在理解你了吗?
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]
答案 2 :(得分:0)
创建一个空字典,收集新的最高字典。我们遍历您的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
的总和(总和为3)。由于我们还没有遇到sender_id
和receiver_id
添加最多3的字典,因此它会被添加到我们的新字典中。
但是,下一个字典的总和也是3.我们检查它的order
值是否大于前一个字典。既然如此,它就会覆盖以前的字典。
然后我们打印新词典的值,因为键只包含sender_id
和receiver_id
的总和。