Удаление дубликатов с использованием пользовательских сравнений

Самый удобный, "путинский" способ удаления дубликатов из списка в основном:

mylist = list(set(mylist))

Но предположим, что ваши критерии подсчета дубликатов зависят от конкретного поля элемента объектов, содержащегося в mylist.

Ну, одно решение состоит в том, чтобы просто определить __eq__ и __hash__ для объектов в mylist, а затем классический list(set(mylist)) будет работать.

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

mylist = list(set(mylist, key = lambda x: x.firstname))

Конечно, это на самом деле не работает, потому что конструктор set не выполняет функцию сравнения, а set требует также хэшируемых клавиш.

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

Ответы

Ответ 1

Вы можете использовать dict вместо набора, в котором ключом dict будут уникальные значения:

d = {x.firstname: x for x in mylist}
mylist = list(d.values())

Ответ 2

Я бы сделал это:

duplicates = set()
newlist = []
for item in mylist:
    if item.firstname not in duplicates:
        newlist.append(item)
        excludes.add(item.firstname)