Python удаляет дубликаты в списке и 1==1,0 True

Мне нужно удалить дубликаты значений в списке, но с set() или же for ... if not in... Цикл Я получаю только частично правильные решения. Например для ['asd', 'dsa', 1, '1', 1.0]

Я получил:

['asd', 'dsa', 1, '1']

но требуемый результат:

['asd', 'dsa', 1, '1', 1.0]

Как мне этого добиться?

2 ответа

Решение

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

In [3]: [value for _, value in frozenset((type(x), x) for x in l)]
Out[3]: [1.0, '1', 1, 'dsa', 'asd']

Мы создаем (временный) frozenset кортежей, содержащих как элемент, так и его тип - чтобы сохранить элементы, которые равны (например, 1, 1.0 и True), но имеют разные типы. Затем мы перебираем его, распаковываем кортежи и получаем элементы (value).

Конечно, мы могли бы использовать обычные set, который является изменяемым, но нам не нужна изменчивость, потому что наш набор временный.

Обратите внимание, что это не обязательно сохранит первоначальный порядок.


Если вам нужно сохранить оригинальный порядок, используйте collections.OrderedDict, которая является хэш-картой (так же, как обычные dict) и поэтому работает аналогично frozenset / set

In [16]: from collections import OrderedDict

In [17]: [value for _, value in OrderedDict.fromkeys((type(x), x) for x in l)]
Out[17]: ['asd', 'dsa', 1, '1', 1.0]

Это хороший пример для шаблона decorate-sort-undecorate, в котором часть sort изменена для создания набора:

dest = [el for el, ignore
        in set((x, type(x))
               for x in src)]

Шаг декорации добавляет тип элемента в набор, так что, например, 1 и 1,0 сравнивают разные. Окончательный список получается путем декорирования набора, т.е. удаления ненужных объектов типа.

Другие вопросы по тегам