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 сравнивают разные. Окончательный список получается путем декорирования набора, т.е. удаления ненужных объектов типа.