Удаление дубликатов из списка состоящего из словарей
В процессе список сортируется по ключу score и уже по ключу track необходимо удалить дубликаты, т.е. между двух одинаковых значений track оставить с наибольшим значением score.
testlist = [
{'score': 67.567, 'track': '03 Greedo & Kenny Beats - Dead Presidents'},
{'score': 69, 'track': '03 Greedo & Kenny Beats - Dead Presidents'},
{'score': 15, 'track': '03 Greedo - Dead Presidents'},
{'score': 120, 'track': '03 Greedo - Dead Presidents'}
]
testlist = sorted(testlist, key=lambda x: x['score'], reverse=True)
Новый список должен иметь следующий вид:
newlist = [
{'score': 120, 'track': '03 Greedo - Dead Presidents'},
{'score': 69, 'track': '03 Greedo & Kenny Beats - Dead Presidents'}
]
Есть идеи решения подобной задачи? Буду рад любой помощи.
Ответы (4 шт):
Автор решения: Bol4onok
→ Ссылка
Можете попробовать так:
testlist = [
{'score': 67.567, 'track': '03 Greedo & Kenny Beats - Dead Presidents'},
{'score': 69, 'track': '03 Greedo & Kenny Beats - Dead Presidents'},
{'score': 15, 'track': '03 Greedo - Dead Presidents'},
{'score': 120, 'track': '03 Greedo - Dead Presidents'}
]
def my_key(d: dict):
return d['track'], d['score']
new_list = sorted(testlist, key=my_key, reverse=True)
answ_list = []
temp = ''
for my_dict in new_list:
if temp != my_dict['track']:
answ_list.append(my_dict)
temp = my_dict['track']
print(answ_list)
Вывод
[{'score': 120, 'track': '03 Greedo - Dead Presidents'}, {'score': 69, 'track': '03 Greedo & Kenny Beats - Dead Presidents'}]
Автор решения: Dmitry
→ Ссылка
Предложу свой вариант. Я буду использовать промежуточный словарь result_dict, который будет содержать ключ = название трэка, а значение = это числовое значение. В сортировке нет необходимости
до обработки
result_dict = {}
for item in testlist:
if result_dict.get(item["track"]):
if item["score"] > result_dict[item["track"]]:
result_dict[item["track"]] = item["score"]
else:
result_dict[item["track"]] = item['score']
print(result_dict)
# OUT
# {'03 Greedo & Kenny Beats - Dead Presidents': 69, '03 Greedo - Dead Presidents': 120}
И теперь можем привести к листу того формата, что нам нужен
result_list = []
for key, value in result_dict.items():
result_list.append(dict(score=value, track=key))
print(result_list)
# OUT
# [{'score': 69, 'track': '03 Greedo & Kenny Beats - Dead Presidents'},
# {'score': 120, 'track': '03 Greedo - Dead Presidents'}]
а вот теперь можно отсортировать
result_list = sorted(result_list, key=lambda x: x['score'], reverse=True)
Автор решения: vadim vaduxa
→ Ссылка
from itertools import groupby
[{'track': a, 'score': max(d['score'] for d in b)} for a, b in groupby(sorted(testlist, key=lambda x: x['track']), key=lambda x: x['track'])]
Автор решения: Namerek
→ Ссылка
from typing import Tuple
from pprint import pprint
testlist = [
{'score': 69, 'track': '03 Greedo & Kenny Beats - Dead Presidents'},
{'score': 15, 'track': '03 Greedo - Dead Presidents'},
{'score': 120, 'track': '03 Greedo - Dead Presidents'},
{'score': 67.567, 'track': '03 Greedo & Kenny Beats - Dead Presidents'},
]
# сортируем по возрастанию наибольшее значение должно оказаться последним
s_list = sorted(testlist, key=lambda x: x['score'])
# Поскольку каждый из словарей списка состоит из 2-х элементов
# имеющих значения, которые можно использовать как ключи словаря
# преобразуем значения словарей списка в словари, где ключом будет
# значение `track`, а значением будет значение `score.
# Поскольку при создании словаря итерацией каждый значение каждого
# существующего ключа будет заменено следующим значением совпадающего ключа
def val_to_dict(item: dict) -> Tuple[str, float]:
return item.get('track'), item.get('score')
new_dict = dict(map(val_to_dict, sorted(testlist, key=lambda x: x['score'])))
# ну и осталось развернуть в исходный вид
def dict_to_val(item: Tuple[str, float]):
k, v = item
return {
'track': k,
'score': v
}
filtered_list = list(map(dict_to_val, new_dict.items()))
pprint(
filtered_list
)
[{'score': 120, 'track': '03 Greedo - Dead Presidents'},
{'score': 69, 'track': '03 Greedo & Kenny Beats - Dead Presidents'}]
А теперь покороче )
from pprint import pprint
testlist = [
{'score': 69, 'track': '03 Greedo & Kenny Beats - Dead Presidents'},
{'score': 15, 'track': '03 Greedo - Dead Presidents'},
{'score': 120, 'track': '03 Greedo - Dead Presidents'},
{'score': 67.567, 'track': '03 Greedo & Kenny Beats - Dead Presidents'},
]
pprint(
[
dict((('track', t), ('score', s))) for item in [
dict(tuple(reversed(i.values())) for i in sorted(testlist, key=lambda x: x['score']))
] for t, s in item.items()
]
)
[{'score': 120, 'track': '03 Greedo - Dead Presidents'},
{'score': 69, 'track': '03 Greedo & Kenny Beats - Dead Presidents'}]