如何找出两个字典列表的差异并返回完整字典项
基于特定键筛选两个字典列表的差异项
现有两个字典列表:
list1 = [ {'name': 'one', 'email': 'one@gmail.com', 'phone': '111'}, {'name': 'two', 'email': 'two@gmail.com', 'phone': '111'}, {'name': 'three', 'email': 'three@gmail.com', 'phone': '333'}, {'name': 'four', 'email': 'four@gmail.com', 'phone': '444'}, ] list2 = [ {'first_name': 'three', 'email': 'three@gmail.com', 'phone_number': '333'}, {'first_name': 'four', 'email': 'four@gmail.com', 'phone_number': '444'}, {'first_name': 'five', 'email': 'five@gmail.com', 'phone_number': '555'}, ]
当前通过以下代码只能得到差异的手机号:
list1_only = list(set([x['phone'] for x in list1]) - set([x['phone_number'] for x in list2])) # 输出:['111']
但期望得到包含完整字典的差异列表:
[ {'name': 'one', 'email': 'one@gmail.com', 'phone': '111'}, {'name': 'two', 'email': 'two@gmail.com', 'phone': '111'} ]
一行实现方案
可以用列表推导式结合集合推导式完成,既简洁又高效:
list1_only = [item for item in list1 if item['phone'] not in {x['phone_number'] for x in list2}]
方案说明
- 先用集合推导式生成list2中所有
phone_number的集合:{x['phone_number'] for x in list2},集合查找的时间复杂度为O(1),比列表查找效率高很多,尤其当数据量较大时。 - 再用列表推导式遍历list1,筛选出
phone不在上述集合中的字典项,直接得到目标结果。
修正错误代码
你之前尝试的这段代码存在逻辑错误:
[x for x in list2 if x['phone_number'] not in list1]
这里x['phone_number']是字符串类型,而list1是字典列表,字符串永远不会存在于字典列表中,所以会输出整个list2。正确的逻辑应该是判断是否在list1的phone集合中,而非直接和list1比较。
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

