1

更新:为了清楚起见,我想检查“名称”和“最后一个”的键值,并且仅当它们不在列表中时才添加。

我有:

lst = [{'name':'John', 'last':'Smith'.... .... (other key-values)... }, 
{'name':'Will', 'last':'Smith'... ... (other key-values)... }]

仅当它与现有字典不完全相同时,我才想将新字典附加到此列表中。

换句话说:

dict1 = {'name':'John', 'last':'Smith'} # ==> wouldn't be appended

但...

dict2 = {'name':'John', 'last':'Brown'} # ==> WOULD be appended

有人可以解释最简单的方法,以及用英语解释解决方案中发生的事情。谢谢!

参考:Python:检查任何列表元素是否是字典中的键

4

4 回答 4

4

由于您要求一种仅检查两个键的方法,即使字典中有其他键:

name_pairs = set((i['name'], i['last']) for i in lst)
if (d['name'], d['last']) not in name_pairs:
    lst.append(d)
于 2012-06-27T03:42:42.200 回答
0

您可以使用此列表推导来做到这一点,只需将所有内容附加到您的列表并运行:

lst.append(dict1)
lst.append(dict2)
[dict(y) for y in set(tuple(x.items()) for x in lst)]

输出是:

[
    {'last': 'Smith', 'name': 'John'},
    {'last': 'Brown', 'name': 'John'},
    {'last': 'Smith', 'name': 'Will'}
]

使用这种方法,您可以添加额外的字段,它仍然可以工作。

于 2012-06-27T03:49:41.553 回答
0

您还可以编写一个小方法来执行此操作并返回列表

def update_if_not_exist(lst, val):
    if len([d for d in lst if (d['name'], d['last']) == (val['name'], val['last'])]) == 0:
        lst.append(val)
    return lst

lst = update_if_not_exist(lst, dict1)
lst = update_if_not_exist(lst, dict2)

它通过过滤原始列表以匹配名称和最后一个键并查看结果是否为空来工作。

于 2012-06-27T04:38:46.410 回答
0
>>> class Person(dict):
...     def __eq__(self, other):
...         return (self['first'] == other['first'] and
...                 self['second'] == other['second'])
...     def __hash__(self):
...         return hash((self['first'], self['second']))

>>> l = [{'first': 'John', 'second': 'Smith', 'age': 23},
...         {'first': 'John', 'second': 'Smith', 'age': 30},
...         {'first': 'Ann', 'second': 'Rice', 'age': 31}]

>>> l = set(map(Person, l))
>>> print l
set([{'first': 'Ann', 'second': 'Rice', 'age': 31},
    {'first': 'John', 'second': 'Smith', 'age': 23}])

Person 类的实例可以用作简单的字典。

于 2012-06-27T05:26:14.683 回答