如何比较多个键值对的两个dicts列表?

时间:2018-01-31 06:12:55

标签: python python-3.x dictionary

我有两个listdict s,一个是另一个的修改子集。我希望根据两个键获得list_one中不会出现在list_two中的元素。例如:

list_one = [{'name': 'alf', 'age': 25},
            {'name': 'alf', 'age': 50},
            {'name': 'cid', 'age': 30}]
list_two = [{'name': 'alf', 'age': 25, 'hair_color': 'brown'},
            {'name': 'cid', 'age': 30, 'hair_color': 'black'}]
desired_list = [{'name': 'alf', 'age': 50}]

我怎样才能做到这一点?我觉得它有某种list comprehension,因此:

desired_list = [x for x in list_one if x['name'] != x2['name'] and x['age'] != x2['age'] 
                for all x2 in list_two]

5 个答案:

答案 0 :(得分:2)

我认为这很容易用两种理解来完成:

代码:

have_2 = {(d['name'], d['age']) for d in list_two}
extra = [d for d in list_one if (d['name'], d['age']) not in have_2]

首先创建我们已有的set tuple,然后检查哪些dict与这些现有密钥中的任何一个都不匹配。

测试代码:

list_one = [{'name': 'alf', 'age': 25},
            {'name': 'alf', 'age': 50},
            {'name': 'cid', 'age': 30}]
list_two = [{'name': 'alf', 'age': 25, 'hair_color': 'brown'},
            {'name': 'cid', 'age': 30, 'hair_color': 'black'}]

have_2 = {(d['name'], d['age']) for d in list_two}
extra = [d for d in list_one if (d['name'], d['age']) not in have_2]

print(extra)

结果:

[{'name': 'alf', 'age': 50}]

答案 1 :(得分:1)

使用此: -

new_list = [i for i,j in zip(list_one,list_two) if i['name']!=j['name'] and i['age']!=j['age']]
print (new_list)

输出

  

[{' name':' alf',' age':50}]

答案 2 :(得分:0)

一种有效的方法是将两个结构转换为dicts,由两个值键入,然后创建结果dict:

grids.stream()
        .flatMap(ms -> ms.getInnerGrid().stream())
        .filter(s -> s.getId().equals(id))
        .findFirst()
        .ifPresent(finalGrid::add);

答案 3 :(得分:0)

key = lambda dct: (dct['name'], dct['age'])
d1 = { key(dct): dct for dct in list_one }
d2 = { key(dct): dct for dct in list_two }
desired_d = { k:v for k,v in d1.items() if k not in d2 }
print(desired_d)
print(desived_d.values())

答案 4 :(得分:0)

另一种可能的解决方案:

>>> list(filter(lambda x: not any([set(x.items()).issubset(y.items()) for y in list_two]), list_one))
[{'age': 50, 'name': 'alf'}]

或:

>>> s2 = [set(i.items()) for i in list_two]
>>> list(filter(lambda x: not any([set(x.items()).issubset(y) for y in s2]), list_one))
[{'age': 50, 'name': 'alf'}]

这种方法的优点是它不需要知道"键" (' age' name')出现在两个字典集中。