在Python中删除重复的列表中的字典
我有一个列表的列表,我想删除具有相同的键和值对的字典。
对于此列表: [{'a': 123}, {'b': 123}, {'a': 123}] 
 我想返回这个: [{'a': 123}, {'b': 123}] 
另一个例子:
 对于这个列表: [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}, {'a': 123, 'b': 1234}] 
 我想返回这个: [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}] 
尝试这个:
 [dict(t) for t in set([tuple(d.items()) for d in l])] 
 该策略是将字典列表转换为元组列表,其中元组包含字典的项目。 由于元组可以被散列,所以你可以使用set来删除重复元素,然后用字典从元组中重新创builddict 。 
哪里:
-   l是原始列表
-   d是列表中的一个字典
-   t是从字典中创build的元组之一
 编辑:如果你想保持sorting,上面的单行不会工作,因为set不会这样做。 但是,用几行代码,你也可以这样做: 
 l = [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}, {'a': 123, 'b': 1234}] seen = set() new_l = [] for d in l: t = tuple(d.items()) if t not in seen: seen.add(t) new_l.append(d) print new_l 
示例输出:
 [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}] 
 注意:正如@alexis指出的那样,可能发生两个具有相同键和值的字典不会产生相同的元组。 如果他们通过不同的添加/删除键历史logging可能会发生这种情况。 如果这是你的问题的情况下,然后考虑按照他的build议sortingd.items() 。 
另一个基于列表parsing的单行:
 >>> d = [{'a': 123}, {'b': 123}, {'a': 123}] >>> [i for n, i in enumerate(d) if i not in d[n + 1:]] [{'b': 123}, {'a': 123}] 
 在这里,因为我们可以使用dict比较,所以我们只保留不在初始列表的其余部分的元素(这个概念只能通过索引n访问,因此使用enumerate )。 
如果您使用嵌套字典(如反序列化的JSON对象),则其他答案将不起作用。 对于这种情况下,你可以使用:
 import json set_of_jsons = {json.dumps(d, sort_keys=True) for d in X} X = [json.loads(t) for t in set_of_jsons] 
如果你想保留订单,那么你可以做
 from collections import OrderedDict print OrderedDict((frozenset(item.items()),item) for item in data).values() # [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}] 
如果顺序没有关系,那么你可以做
 print {frozenset(item.items()):item for item in data}.values() # [{'a': 3222, 'b': 1234}, {'a': 123, 'b': 1234}] 
有时旧式循环仍然有用。 这个代码比jcollado的长一点,但是很容易阅读:
 a = [{'a': 123}, {'b': 123}, {'a': 123}] b = [] for i in range(0, len(a)) if a[i] not in a[i+1:] b.append(a[i]) 
你可以使用一个集合,但是你需要把这些字典变成一个可排列的types。
 seq = [{'a': 123, 'b': 1234}, {'a': 3222, 'b': 1234}, {'a': 123, 'b': 1234}] unique = set() for d in seq: t = tuple(d.iteritems()) unique.add(t) 
独特的现在等于
 set([(('a', 3222), ('b', 1234)), (('a', 123), ('b', 1234))]) 
为了得到答案:
 [dict(x) for x in unique]