List of Dicts comparision to match between lists and detect value changes in Python

别等时光非礼了梦想. 提交于 2019-12-24 07:46:11

问题


I have a list of dictionaries that I get back from a web service call,

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

I need to compare the results from the previous call to the service and pull out changes. So on the next call I may get:

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

The ordering is not guaranteed and nor is the length of list. The names won't change. The actual data has several more keys, but I'm only concerned with 'val'.

I am trying to find a way to get back a list of the names that have had their values change between calls only for the names that are in both lists.

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

回答1:


I'd build an auxiliary dict to store listA's information more sensibly:

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

then the task becomes very easy:

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



回答2:


First off, please turn that braindead format from your library into a real dict:

>>> 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'}

Then, this becomes relatively easy:

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


来源:https://stackoverflow.com/questions/2412562/list-of-dicts-comparision-to-match-between-lists-and-detect-value-changes-in-pyt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!