Сравнение списков Dicts для соответствия между списками и обнаружения изменений значений в Python - PullRequest
1 голос
/ 10 марта 2010

У меня есть список словарей, которые я получаю после вызова веб-службы,

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 ]

6 голосов
/ 10 марта 2010

Я бы создал вспомогательный диктат для более разумного хранения информации 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']]]
0 голосов
/ 10 марта 2010

Прежде всего, пожалуйста, превратите этот формат мозговой смерти из вашей библиотеки в настоящий диктант:

>>> 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']
>>>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...