如何在python中检测dict数组中的重复键值?

时间:2015-05-26 23:28:03

标签: python dictionary

鉴于以下代码:

a = [{"name": "Sport"}, {"name": "Games"}, {"name": "Videos"}, {"name": "Sport"}]

如何判断变量中的另一个dict是否具有相同的名称值?在上面的示例中,结果应返回“Sport”。

提前致谢。

4 个答案:

答案 0 :(得分:9)

很多很棒的方法。 Python中的规范可能是使用collections.Counter

from collections import Counter

c = Counter([d['name'] for d in a])
for value,count in c.items():
    if count > 1:
        print(value)

如果您需要知道的是某些内容是否重复(不是重复的次数),您只需使用seen集就可以简化。

seen = set()
for d in a:
    val = d['name']
    if val in seen:
        print(val)
    seen.add(val)

可能最过于设计的方法就是按照他们的名字来排序这些名称"值,然后运行groupby并检查每个组的长度。

from itertools import groupby
from operator import itemgetter

namegetter = itemgetter('name')

new_a = sorted(a, key=namegetter)

groups = groupby(new_a, namegetter)

for groupname, dicts in groups:
    if len(list(dicts)) > 1:
        print(groupname)

答案 1 :(得分:2)

这建立在@ AdamSmith的答案之上,但由于使用了列表推导,它有点短:

from collections import Counter

a = [{"name": "Sport"}, {"name": "Games"}, {"name": "Videos"}, {"name": "Sport"}]
[name for name, count in Counter(x['name'] for x in a).items() if count > 1]

因此,我们将获得重复列表:

['Sport']

答案 2 :(得分:1)

还有几种方式:

>>> seen = set()
>>> {n for n in (d['name'] for d in a) if n in seen or seen.add(n)}
{'Sport'}

>>> seen = set()
>>> {n for d in a for n in [d['name']] if n in seen or seen.add(n)}
{'Sport'}

>>> k, seen = 'name', set()
>>> {d[k] for d in a if d[k] in seen or seen.add(d[k])}
{'Sport'}

>>> seen = {}
>>> {d['name'] for i, d in enumerate(a) if seen.setdefault(d['name'], i) != i}
{'Sport'}

>>> seen = {}
>>> {d['name'] for d in a if seen.setdefault(d['name'], id(d)) != id(d)}
{'Sport'}

>>> x = set(), set()
>>> for n in (d['name'] for d in a): x[n in x[0]].add(n)
>>> x[1]
{'Sport'}

答案 3 :(得分:0)

集合是一个有用的数据结构,因为它们具有恒定的时间插入和包含测试,与列表不同。

def first_duplicate_name(dictlist):
    seen = set()
    seen_add = seen.add
    for dct in dictlist:
        k = dct['name']
        if k in seen: # constant time AKA O(1)
            return k
        else:
            seen_add(k) # also O(1)