Как дедуплицировать словари, содержащие один и тот же идентификатор в python

#python #python-3.x #list #dictionary

Вопрос:

Я хотел бы дедуплицировать словари, содержащие одно и то же значение «идентификатор».

список диктантов:

 example = [{'term': 'potato', 'id': 10}, {'term': 'potatoes', 'id': 10}, {'term': 'apple', 'id': 7}]

 

Желаемый результат:

 example = [{'term': 'potato', 'id': 10}, {'term': 'apple', 'id': 7}]
 

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

пример кода (попытка):

 import ast 

new_list = []
seen_keys = set()
for term in example:
    d = ast.literal_eval(term) #had to convert a string-dict to a dict first because the dictionaries were transformed to a string in a Solr database
    if d['id'] not in seen_keys:
        new_list.append(d)
        seen_keys.add(d['id'])
 

Ответ №1:

Нет необходимости использовать ast.literal_eval :

 example = [{'term': 'potato', 'id': 10}, {'term': 'potatoes', 'id': 10}, {'term': 'apple', 'id': 7}]

seen_keys = set()
new_list = []
for d in example:
    if d["id"] not in seen_keys:
        seen_keys.add(d["id"])
        new_list.append(d)

print(new_list)
 

Выход

 [{'term': 'potato', 'id': 10}, {'term': 'apple', 'id': 7}]
 

Если вы заинтересованы в O(n) однострочном, используйте:

 new_list = list({ d["id"] : d for d in example[::-1]}.values())[::-1]
print(new_list)
 

Выход (из однострочного)

 [{'term': 'potato', 'id': 10}, {'term': 'apple', 'id': 7}]
 

Ответ №2:

Мне вроде как нравится создавать универсальную uniqueBy функцию для такого рода проблем:

 
example = [{'term': 'potato', 'id': 10}, {'term': 'potatoes', 'id': 10}, {'term': 'apple', 'id': 7}]

def uniqueBy (f):
    return lambda a: { f(x): x for x in a }

uniqueById = uniqueBy(lambda x: x['id'])
    
print("{}".format(uniqueById(example).values()))
 

Ответ №3:

Или используйте понимание однострочного списка с enumerate :

 >>> [d for i, d in enumerate(example) if d['id'] not in [x['id'] for x in example[i   1:]]]
[{'term': 'potatoes', 'id': 10}, {'term': 'apple', 'id': 7}]
>>> 
 

Ответ №4:

вы можете попробовать это

 example = [
    {"term": "potato", "id": 10},
    {"term": "potatoes", "id": 10},
    {"term": "apple", "id": 7},
]

ids = set()

for item in example:
    ids.add(item["id"])

results = []

for item in example:
    if item["id"] in ids:
        results.append(item)
        ids.remove(item["id"])

print(results)
 

Ответ №5:

Это можно сделать так же легко, как:

 test_list = [{'term': 'potato', 'id': 10}, {'term': 'potatoes', 'id': 10}, {'term': 'apple', 'id': 7}]


res = []
[res.append(x) for x in test_list if x['id'] not in [y['id'] for y in res]]
print(res)
 

Ответ №6:

После небольшого редактирования вашего кода:

 example = [{'term': 'potato', 'id': 10}, {'term': 'potatoes', 'id': 10}, {'term': 'apple', 'id': 7}]
new_list = []
seen_keys = set()

for i in example:
    if i['id'] not in seen_keys:
        new_list.append(i)
        seen_keys.add(i['id'])
        
print(new_list)
 

Выход:

 [{'term': 'potato', 'id': 10}, {'term': 'apple', 'id': 7}]