Как удалить дубликаты из списка в Python?
В списке есть повторяющиеся элементы, нужно оставить только уникальные. Слышал, что можно через set, но тогда вроде теряется порядок. Как убрать повторы из списка и при этом, если нужно, сохранить исходный порядок?
2 ответа
Если порядок неважен — самый короткий способ через set:
nums = [3, 1, 2, 3, 1]
unique = list(set(nums)) # порядок не гарантирован
set хранит только уникальные значения, но не сохраняет порядок, поэтому результат может оказаться, например, [1, 2, 3].
Если порядок первого появления важен — в современном Python (3.7+) словари сохраняют порядок, и есть красивый трюк:
unique = list(dict.fromkeys(nums)) # [3, 1, 2]
dict.fromkeys делает ключи из элементов (ключи уникальны по определению), а порядок вставки сохраняется. Это лучший способ «убрать дубликаты, сохранив порядок».
Классический ручной вариант — через множество «виденных»:
seen = set()
result = []
for x in nums:
if x not in seen:
seen.add(x)
result.append(x)
Частая ошибка — думать, что set сохранит порядок: иногда он случайно совпадает на маленьких числах, и люди делают неверный вывод. Не полагайтесь на это — для гарантии порядка берите dict.fromkeys.
Важно: через set можно прогонять только хешируемые элементы (числа, строки, кортежи). Списки внутри списка так не получится — для них нужен ручной цикл.
Если элементы — это словари или списки (нехешируемые), set не сработает, выпадет TypeError: unhashable type. Тогда фильтруйте вручную:
seen = []
result = [x for x in items if x not in seen and not seen.append(x)]
Хотя такой однострочник хитрый и плохо читается — лучше обычный цикл с проверкой if x not in result. Для больших списков он медленный (O(n²)), но для нехешируемых данных других простых вариантов почти нет.