Python 按dict的最高值筛选dict列表,并考虑反向值
假设我有如下数据:Python 按dict的最高值筛选dict列表,并考虑反向值,python,Python,假设我有如下数据: 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
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\u data
,因此我将获得sender\u id
和receiver\u id
的order
值最高的项目列表,但对我来说receiver\u id=1,sender\u id=2
与sender\u id=1,receiver\u id=2
所以,我的问题是,有没有更具pythonic/更快的方法来做到这一点?或者有人可以指出改进的方向
p.S.如果有人能提出一个可以理解的标题,我将不胜感激。对不起,我的英语不好。您可以使用字典,将发送方和接收方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
创建一个空字典,它将收集新的最高字典。我们反复检查您的
筛选\u数据
,并检查发送方id
和接收方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()
例如,它将遍历第一个字典并计算其接收方id
和发送方id
的总和(总和为3)。由于我们还没有遇到一个“发送者id”和“接收者id”合计为3的词典,因此它被添加到我们的新词典中
然而,下一本词典也有一个3的总和。我们检查它的顺序
值是否大于上一个字典。因为它是,它覆盖了以前的字典
然后我们打印新字典的值,因为键只包含
sender\u id
和receiver\u id
的和,我现在明白你的意思了吗
从itertools导入groupby
grp=groupby(筛选数据,λx:(最小值(x[“发送方id”]、x[“接收方id”]、最大值(x[“发送方id”]、x[“接收方id”]))
l=[已排序(g,key=lambda x:-x[“顺序”])[0]表示grp中的k,g]
我尽了最大的努力,但我不明白你在问什么,用列表理解法python@KalpeshDusane列表竞争只是一种句法上的糖分。我不明白你的建议。我想问的是,标准库中可能有一些函数可以使代码更短、更可读。因此,对于每对发送方和接收方,无论谁是谁,您都想要最高的顺序?您所说的“发送方id和接收方id的最大顺序值”是什么意思?好主意!使用sender
和receiver
的组合作为键。会有问题,例如当我有sender 5
和receiver 1
和sender 4
和receiver 2
时,因为它们会产生相同的总数
@SardorbekImomaliev啊,我当时一定误解了这个问题。如果发生这种情况,会发生什么?您是对值求和,而不是对它们进行组合。我的意思是,发送方5和接收方1与发送方1和接收方5相同(值相反)。但是发送者5和接收者1与发送者2和接收者4不同。@SardorbekImomaliev发送者和接收者的值可能会相同吗?在我的例子中不会。因为他们在“聊天”。但总的来说,我看不出有什么不同。即使在sender\u id==receiver\u id
时,它也应该工作。注意:要使其工作,filter\u data
必须按要分组的键进行排序。字典中的顺序或多或少是随机的,因此它可能适用于小示例,但在其他情况下会失败。另外,为什么不使用max
,而不是sorted(…)[0]
?关于需要按分组对数据进行排序这一点,您是对的。关于为什么不使用max-因为我们需要检索项目本身,而不仅仅是最大顺序。您可以使用与排序max
相同的key
功能(只需删除-
):max(g,key=lambda x:x[“order”])
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()