Python:如何基于number键值找出两个字典列表的差异项?
问题:基于number键找出仅存在于test_list1的字典项
给定两个字典列表:
test_list1 = [{"name" : "name1", "number": "number1", "data": "data1"}, {"name" : "name2", "number": "number2", "data": "data2"}, {"name" : "name3", "number": "number3", "data": "data3"}, {"name" : "name5", "number": "number5", "data": "data5"}] test_list2 = [{"name" : "name1", "number": "number1", "data": "data5"}, {"name" : "name2", "number": "number2", "data": "data2"}, {"name" : "name3", "number": "number3", "data": "data3"}, {"name" : "name4", "number": "number4", "data": "data4"}]
尝试用以下列表推导式获取目标项:
res2 = [i for i in test_list1 for j in test_list2 if i.get("number") != j.get("number")]
但结果包含大量重复项,无法得到预期的仅{"name" : "name5", "number": "number5", "data": "data5"}这一项,如何正确实现?
错误原因分析
你写的双重循环列表推导式逻辑有误:只要test_list1中的项和test_list2里任意一个项的number不等,就会把这个test_list1的项加入结果。比如test_list1里的name1会和test_list2里的name2、name3、name4的number不等,所以会被重复添加3次,最终结果出现大量重复。
正确实现方法
方法一:利用集合提高查询效率(推荐)
先提取test_list2中所有number值存入集合(集合的成员查询是O(1)时间复杂度,效率远高于列表),再遍历test_list1筛选符合条件的项:
# 提取test_list2的所有number到集合 test2_numbers = {item["number"] for item in test_list2} # 筛选test_list1中number不在集合内的项 res = [item for item in test_list1 if item["number"] not in test2_numbers]
方法二:用any()函数判断存在性
适合数据量较小的场景,通过any()检查test_list2中是否存在与当前项number匹配的项,只有完全不存在匹配项时才保留:
res = [item for item in test_list1 if not any(item["number"] == j["number"] for j in test_list2)]
两种方法的执行结果均为:
[{"name": "name5", "number": "number5", "data": "data5"}]
完全符合预期。
内容的提问来源于stack exchange,提问作者ratzip
相关产品推荐
相关产品推荐

