Как убрать дубликаты из списка диктов? - PullRequest
1 голос
/ 23 марта 2019

У меня есть список словарей в 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'}]

(синтаксический анализ некоторых текстовых файлов данных)

Что я хочу сделать:

Если категория иимя одно и то же. Я хочу оставить первое появление записи пакета и удалить остальные, поэтому итоговый вывод будет выглядеть так:

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

Как мне этого добиться?Я попытался преобразовать список словарей в словарь, а затем перебрать его с помощью dict.items(), но безуспешно.

Ответы [ 3 ]

2 голосов
/ 23 марта 2019

Используйте itertools.groupby и возьмите сначала из каждой группы:

def uniq(lst):
    for _, grp in itertools.groupby(lst, lambda d: (d['category'], d['name'])):
        yield list(grp)[0]
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'}]
print(list(uniq(lst))
2 голосов
/ 23 марта 2019

Используйте set для отслеживания всех пар (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'}]
0 голосов
/ 23 марта 2019

Предполагая, что вы хотите сохранить последнюю версию, вы можете создать словарь, содержащий информацию о программном обеспечении для последней версии каждой пары категории / имени. Затем получите список значений из этого словаря словарей:

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

lastVersion = dict()
for softInfo in software:
    key = (softInfo['category'],softInfo['name'])
    if key not in lastVersion or lastVersion[key]['version'] < softInfo['version']:
        lastVersion[key] = softInfo
software = list(lastVersion.values())

print(software)

# [{'category': 'software', 'name': 'irssi', 'version': '1.2.0'},
#  {'category': 'software', 'name': 'hexchat', 'version': '2.14.2'}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...