首页 > 解决方案 > 如何从字典列表中删除重复项?

问题描述

我在python中有一个字典列表,如下所示:

[{'category': 'software', 'name': 'irssi', 'version': '1.2.0'},
 {'category': 'software', 'name': 'irssi', 'version': '1.1.2'},
 {'category': 'software', 'name': 'hexchat', 'version': '2.14.2'}]

(解析一些数据txt文件)

我想做的事:

如果类别和名称相同,我想保留包条目的第一个外观并删除其余部分,因此最终输出如下所示:

[{'category': 'software', 'name': 'irssi', 'version': '1.2.0'},
{'category': 'software', 'name': 'hexchat', 'version': '2.14.2'}]

我应该如何实现这一目标?我尝试将字典列表转换为字典,然后对其进行迭代,dict.items()但没有运气。

标签: pythonlistdictionary

解决方案


使用 aset来跟踪(category, name)您已经看到的所有对:

lst = [
    {'category': 'software', 'name': 'irssi', 'version': '1.2.0'},
    {'category': 'software', 'name': 'irssi', 'version': '1.1.2'},
    {'category': 'software', 'name': 'hexchat', 'version': '2.14.2'}
]

seen = set()
result = []

for dic in lst:
    key = (dic['category'], dic['name'])
    if key in seen:
        continue

    result.append(dic)
    seen.add(key)

print(result)
# output: [{'category': 'software', 'name': 'irssi', 'version': '1.2.0'},
#          {'category': 'software', 'name': 'hexchat', 'version': '2.14.2'}]

这可以概括为一个函数:

def keep_first(iterable, key=None):
    if key is None:
        key = lambda x: x

    seen = set()
    for elem in iterable:
        k = key(elem)
        if k in seen:
            continue

        yield elem
        seen.add(k)
>>> list(keep_first(lst, lambda d: (d['category'], d['name'])))
[{'category': 'software', 'name': 'irssi', 'version': '1.2.0'},
 {'category': 'software', 'name': 'hexchat', 'version': '2.14.2'}]

推荐阅读