为了账号安全,请及时绑定邮箱和手机立即绑定

忽略某些键的两个字典列表之间的区别

忽略某些键的两个字典列表之间的区别

月关宝盒 2022-04-23 17:20:51
我想通过仅比较字典的某些键来找到两个字典列表之间的区别。a = [    {"fruit": "apple", "colour": "green", "notes":"one a day"},    {"vegetable": "tomato", "colour": "red", "origin": "asia"}]b = [    {"fruit": "apple", "colour": "green", "origin": "central asia"},    {"fruit": "strawberry", "colour": "red", "notes":"vitamin c"}]在示例中,我想忽略比较逻辑notes,origin但仍将它们保留在输出中。预期结果:output = [    {"vegetable": "tomato", "colour": "red", "origin": "asia"},    {"fruit": "strawberry", "colour": "red", "notes":"vitamin c"}]我尝试使用in条件,但它比较了所有字典键:difference = [i for i in a if i not in b]我试图调整这个解决方案,但它比较单个字典条目而不是整个集合的问题:def equal_dicts(a, b):    ignore_keys = ("notes", "origin")    ka = set(a).difference(ignore_keys)    kb = set(b).difference(ignore_keys)    return ka == kb and all(a[k] == b[k] for k in ka) for item in a:        if not equal_dicts(a, b):            print('same dictionary')
查看完整描述

2 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

你可以这样做:


def list_diff(a, b):

    return [a_item for a_item in a if not any(equal_dicts(a_item, b_item) for b_item in b)]


output = list_diff(a, b) # Everythin that's in a but not in b

output.extend(list_diff(b, a)) # Everythin that's in b but not in a 

这给了你:


output = [

  {'vegetable': 'tomato', 'colour': 'red', 'origin': 'asia'}, 

  {'fruit': 'strawberry', 'colour': 'red', 'notes': 'vitamin c'}

]


查看完整回答
反对 回复 2022-04-23
?
萧十郎

TA贡献1815条经验 获得超13个赞

您可以先过滤掉要忽略的键,然后正常比较字典。


如果您仍然希望将忽略的键包含在比较结果中,则需要对该方法进行一些修改 - 例如将过滤后的结果与原始结果进行比较a并b添加缺失的字段。


ignored_keys = {'notes', 'origin'}

filtered_a = [{k:v for k,v in sub_dict.items() if k not in ignored_keys} for sub_dict in a]

filtered_b = [{k:v for k,v in sub_dict.items() if k not in ignored_keys} for sub_dict in b]

那么区别是:


in_a_not_b = [elem for elem in filtered_a if elem not in filtered_b]

in_b_not_a = [elem for elem in filtered_b if elem not in filtered_a]

full_diff = in_a_not_b + in_b_not_a

至于被忽略的键,我可能会在合并结果之前添加它们,因为我们知道结果来自哪里......


或者没有太多思考的懒惰版本(例如:可能有更有效/更智能的方法,但我喜欢 dict/list 理解并且讨厌“手动”循环):从过滤的东西到原始 dict 的映射。


dicts 是不可散列的,但我们可以将过滤后的“dicts”变成成对的元组:


ignored_keys = {'notes', 'origin'}

filtered_a = {tuple((k,v) for k,v in sub_dict.items() if k not in ignored_keys):sub_dict for sub_dict in a}

filtered_b = {tuple((k,v) for k,v in sub_dict.items() if k not in ignored_keys):sub_dict for sub_dict in b}


#compare on keys but get the original as the result

in_a_not_b = [filtered_a[elem] for elem in filtered_a if elem not in filtered_b]

in_b_not_a = [filtered_b[elem] for elem in filtered_b if elem not in filtered_a]

full_diff = in_a_not_b + in_b_not_a

结果:


>>> full_diff

[{'vegetable': 'tomato', 'colour': 'red', 'origin': 'asia'}, {'fruit': 'strawberry', 'colour': 'red', 'notes': 'vitamin c'}]


查看完整回答
反对 回复 2022-04-23
  • 2 回答
  • 0 关注
  • 122 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号