在Python中比较字典列表以匹配并检测值变化

1 投票
2 回答
1084 浏览
提问于 2025-04-15 20:13

我有一个字典列表,这是我从一个网络服务调用中得到的结果,

listA = [{'name':'foo', 'val':'x'}, 
         {'name':'bar', 'val':'1'},
         {'name':'alice','val':'2'}]

我需要把这次调用的结果和上一次的结果进行比较,找出有哪些变化。所以在下一次调用时,我可能会得到:

listB = [{'name':'foo', 'val':'y'},
         {'name':'bar', 'val':'1'},
         {'name':'eve','val':'z'}]

列表的顺序和长度都是不确定的,名字不会改变。实际的数据还有很多其他的键,但我只关心'val'这个键。

我想找到一种方法,获取一个名字列表,这些名字在两次调用中都有出现,并且它们的值发生了变化。

changed = ['foo'] # or [{'name':'foo'}]

2 个回答

0

首先,请把你库里的那个傻乎乎的格式转换成一个真正的字典:

>>> listA = [{'name':'foo', 'val':'x'},{'name':'bar', 'val':'1'},{'name':'alice','val':'2'}]
>>> listB = [{'name':'foo', 'val':'y'},{'name':'bar', 'val':'1'},{'name':'eve','val':'z'}]
>>> def dicter(l):
...     return dict([(i['name'],i['val']) for i in l])
...
>>> listA=dicter(listA)
>>> listA
{'foo': 'x', 'bar': '1', 'alice': '2'}
>>> listB=dicter(listB)
>>> listB
{'foo': 'y', 'bar': '1', 'eve': 'z'}

然后,这样就变得相对简单了:

>>> answer = [k for k,v in listB.items() if k in listA and listA[k] != v]
>>> answer
['foo']
>>>
6

我会建立一个辅助字典,用来更合理地存储listA的信息:

auxdict = dict((d['name'], d['val']) for d in listA)

这样一来,任务就变得非常简单了:

changed = [d['name'] for d in listB 
           if d['name'] in auxdict and d['val'] != auxdict[d['name']]]

撰写回答