查找python中两个词典列表的差异
我有两本字典,如下所示:查找python中两个词典列表的差异,python,Python,我有两本字典,如下所示: prev = [ { 'id': 0, 'name': 'a' }, { 'id': 1, 'name': 'b' }, { 'id': 2, 'name': 'c' } ] current = [ { 'id': 1, 'name': 'b' }, { 'id': 2, 'name': 'c' }, { 'id': 3, 'name': 'e' }, { 'id': 4, 'name': 'f' } ] 我想得到它们之
prev = [
{ 'id': 0, 'name': 'a' },
{ 'id': 1, 'name': 'b' },
{ 'id': 2, 'name': 'c' }
]
current = [
{ 'id': 1, 'name': 'b' },
{ 'id': 2, 'name': 'c' },
{ 'id': 3, 'name': 'e' },
{ 'id': 4, 'name': 'f' }
]
我想得到它们之间的差异,结果如下:
result = [
{ 'id': 3, 'name': 'e' },
{ 'id': 4, 'name': 'f' }
]
结果列表中只应显示这两个的差异,mu解决方案如下所示
common = []
for c in current:
for p in prev:
if c['name'] == p['name']:
common.append(c)
print(common)
事实上,我正试图找出两者之间的共同点,然后从current
列表中减去它,但我不知道如何处理它,我卡住了!如果解决问题的程序有误,如果能找到这两个差异,我们将不胜感激
我试着搜索了很多,但我找到的结果只是比较了两个整数列表,在我的例子中就是字典列表
**还注意到ID键只是用于分隔那些项目,让我们按名称比较,让我想从“代码>当前的中删除公文,剩下的只是在<代码>当前< /代码>列表中,我的意思是我不需要<代码>名称:A< <代码> >代码>名称:B< <代码> > <代码> >代码>列表
这将完成任务prev=[{'id':0,'name':'a'},{'id':1,'name':'b'},{'id':2,'name':'c'}]
当前=[{'id':1,'name':'b'},{'id':2,'name':'c'},{'id':3,'name':'e'},{'id':4,'name':'f'}]
公共=[]
对于电流中的c:
如果不存在(c['id']==p['id']和c['name']==p['name']表示上一页中的p):
公共追加(c)
打印(通用)
如果iterable的任何元素为True,则返回True。如果iterable为空,则返回False
此外,正如@wjandrea在评论中指出的,这
new=[c代表当前的c,如果c不在上一个中]
这也是一个公平而美好的回答。但是请注意,只有在比较整个dicts时,它才起作用,这样做就可以了
prev=[{'id':0,'name':'a'},{'id':1,'name':'b'},{'id':2,'name':'c'}]
当前=[{'id':1,'name':'b'},{'id':2,'name':'c'},{'id':3,'name':'e'},{'id':4,'name':'f'}]
公共=[]
对于电流中的c:
如果不存在(c['id']==p['id']和c['name']==p['name']表示上一页中的p):
公共追加(c)
打印(通用)
如果iterable的任何元素为True,则返回True。如果iterable为空,则返回False
此外,正如@wjandrea在评论中指出的,这
new=[c代表当前的c,如果c不在上一个中]
这也是一个公平而美好的回答。但是请注意,只有在比较整个dicts时,它才起作用。如果我理解正确,您只需要出现在current中而没有出现在prev中的项目 像这样的东西应该有用
prev_names = set(map(lambda x: x['name'], prev))
new_items = [item for item in current if item['name'] not in prev_names]
new_items # [{'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
如果我理解正确,您只需要出现在current中而没有出现在prev中的项目 像这样的东西应该有用
prev_names = set(map(lambda x: x['name'], prev))
new_items = [item for item in current if item['name'] not in prev_names]
new_items # [{'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
简单的
从您发布的数据中,您可以比较整个dict,因此只需在current
中查找不在prev
中的dict即可:
new = [d for d in current if d not in prev]
print(new) # -> [{'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
复杂的
如果您的真实数据可能具有不同的id
s,则解决方案需要更加复杂
因为只有名称
才是重要的,所以请创建一组通用名称。然后,您可以在dict上循环,检查名称是否在公共集合中
prev = [{'id': 0, 'name': 'a'}, {'id': 1, 'name': 'b'}, {'id': 2, 'name': 'c'}]
current = [{'id': 1, 'name': 'b'}, {'id': 2, 'name': 'c'}, {'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
prev_names, current_names = [{d['name'] for d in x} for x in (prev, current)] # [{'c', 'b', 'a'}, {'c', 'b', 'f', 'e'}]
common_names = prev_names & current_names # {'b', 'c'}
new = [d for d in current if d['name'] not in common_names]
print(new) # -> [{'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
这也很容易适应在prev
中获取不常见的名称:
old = [d for d in prev if d['name'] not in common_names]
print(old) # -> [{'id': 0, 'name': 'a'}]
简单的
从您发布的数据中,您可以比较整个dict,因此只需在current
中查找不在prev
中的dict即可:
new = [d for d in current if d not in prev]
print(new) # -> [{'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
复杂的
如果您的真实数据可能具有不同的id
s,则解决方案需要更加复杂
因为只有名称
才是重要的,所以请创建一组通用名称。然后,您可以在dict上循环,检查名称是否在公共集合中
prev = [{'id': 0, 'name': 'a'}, {'id': 1, 'name': 'b'}, {'id': 2, 'name': 'c'}]
current = [{'id': 1, 'name': 'b'}, {'id': 2, 'name': 'c'}, {'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
prev_names, current_names = [{d['name'] for d in x} for x in (prev, current)] # [{'c', 'b', 'a'}, {'c', 'b', 'f', 'e'}]
common_names = prev_names & current_names # {'b', 'c'}
new = [d for d in current if d['name'] not in common_names]
print(new) # -> [{'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
这也很容易适应在prev
中获取不常见的名称:
old = [d for d in prev if d['name'] not in common_names]
print(old) # -> [{'id': 0, 'name': 'a'}]
代码
import itertools
list(itertools.filterfalse(lambda x: x in prev, current))
输出:
[{'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
代码
import itertools
list(itertools.filterfalse(lambda x: x in prev, current))
输出:
[{'id': 3, 'name': 'e'}, {'id': 4, 'name': 'f'}]
根据所有答案,这里有一个小基准
import timeit
进口itertools
prev=[{'id':0,'name':'a'},{'id':1,'name':'b'},{'id':2,'name':'c'}]
current=[{'id':1,'name':'b'},{'id':2,'name':'c'},{'id':3,'name':'e'},{'id':4,'name':'f'}]
def f1():
prev_names=set(映射(lambda x:x['name'],prev))
新项目=[如果项目['name']不在上一个项目名称中,则当前项目中的项目对应项目]
返回新的\u项目
def f2():
公共=[]
对于电流中的c:
如果不存在(c['id']==p['id']和c['name']==p['name']表示上一页中的p):
公共追加(c)
返回公共
def f3():
返回列表(itertools.filterfalse(lambda x:x在上一个版本中,当前版本))
打印(f1())
打印(timeit.timeit(“f1()”,setup=“from”\uuuuu main\uuuuuu导入f1”))
打印(f2())
打印(timeit.timeit(“f2()”,setup=“from”\uuuuu main\uuuuuu导入f2”))
打印(f3())
打印(timeit.timeit(“f3()”,setup=“from”\uuuuu main\uuuuuu导入f3”))
[{'id':3,'name':'e'},{'id':4,'name':'f'}]
0.8235890520736575
[{'id':3,'name':'e'},{'id':4,'name':'f'}]
2.0767332719406113
[{'id':3,'name':'e'},{'id':4,'name':'f'}]
0.864271447993815
根据所有答案,这里有一个小基准
import timeit
进口itertools
prev=[{'id':0,'name':'a'},{'id':1,'name':'b'},{'id':2,'name':'c'}]
current=[{'id':1,'name':'b'},{'id':2,'name':'c'},{'id':3,'name':'e'},{'id':4,'name':'f'}]
def f1():
prev_names=set(映射(lambda x:x['name'],prev))
新项目=[如果项目['name']不在上一个项目名称中,则当前项目中的项目对应项目]
返回新的\u项目
def f2():
公共=[]
对于电流中的c:
如果不存在(c['id']==p['id']和c['name']==p['name']表示上一页中的p):
公共追加(c)
返回公共
def f3():
返回列表(itertools.filterfalse(lambda x:x在上一个版本中,当前版本))
打印(f1())
打印(timeit.timeit(“f1()”,setup=“from”\uuuuu main\uuuuuu导入f1”))
打印(f2())
打印(timeit.timeit(“f2()”,setup=“from”\uuuuu main\uuuuuu导入f2”))
打印(f3())
打印(timeit.timeit(“f3()”,setup=“from”\uuuuu main\uuuuuu导入f3”))
<代码