Как получить уникальные значения из списка в Python: все способы

Раздел: Структуры данных -> Списки

Получение уникальных значений из списка

Извлечение неповторяющихся элементов из списка - часто встречающаяся задача при обработке данных. В Python существует несколько подходов, различающихся по производительности, сохранению порядка, типу элементов и удобству чтения. Рассмотрим основные варианты.

Как получить уникальные значения, сохраняя порядок и обеспечивая максимальную производительность?

Наиболее эффективное решение для списков любого размера - использование dict.fromkeys() (начиная с Python 3.7, где словари сохраняют порядок вставки). Оно работает за O(n) и подходит для хешируемых типов данных.


my_list = [3, 1, 2, 3, 1, 4, 5, 2]
unique = list(dict.fromkeys(my_list))
print(unique)  # [3, 1, 2, 4, 5]

посчитать список python (посчитать элементы списка в python)

Если порядок не важен, set() даёт ещё более высокую скорость и простоту:


unique_set = list(set(my_list))
print(unique_set)  # [1, 2, 3, 4, 5] (порядок произвольный)

функция длина списка в python (длина списка в python)

Как сделать уникализацию простым циклом с проверкой?


my_list = [3, 1, 2, 3, 1]
unique = []
for x in my_list:
    if x not in unique:
        unique.append(x)
print(unique)  # [3, 1, 2]

количество чисел python (количество чисел в python)

Проблема: O(n²) из-за оператора in для списка. На больших данных (десятки тысяч элементов) производительность резко падает. Решение: использовать вспомогательное множество для быстрой проверки.

Как избавиться от дубликатов с сохранением исходного порядка через OrderedDict?


from collections import OrderedDict
my_list = [3, 1, 2, 3, 1]
unique = list(OrderedDict.fromkeys(my_list))
print(unique)  # [3, 1, 2]

получить индекс python (получение индекса элемента в python)

Проблема: избыточность, если используется Python 3.7+, так как обычный dict уже упорядочен. Решение: заменить на dict.fromkeys().

Как получить уникальные значения с помощью list comprehension и условия?


my_list = [3, 1, 2, 3, 1]
seen = set()
unique = [x for x in my_list if not (x in seen or seen.add(x))]
print(unique)  # [3, 1, 2]

Python список значений (список значений в python)

Здесь используется побочный эффект метода seen.add(x), который возвращает None, а условие x in seen проверяет наличие.

Проблема: код выглядит неочевидным, сложно читается. Решение: предпочесть явный цикл или dict.fromkeys().

Как обработать списки с нехэшируемыми элементами (например, вложенные списки)?


my_list = [[1,2], [3,4], [1,2], [5,6]]
unique = []
seen = []
for item in my_list:
    if item not in seen:
        unique.append(item)
        seen.append(item)
print(unique)  # [[1, 2], [3, 4], [5, 6]]

Python список чисел (список чисел в python)

Проблема: O(n²) и невозможно использовать set или dict из-за нехэшируемости списков. Решение: преобразовать каждый элемент в хешируемый тип (например, кортеж) перед добавлением в множество.

Как применить библиотеку pandas для уникальных значений?


import pandas as pd
my_list = [3, 1, 2, 3, 1, 4]
unique = pd.Series(my_list).unique().tolist()
print(unique)  # [3, 1, 2, 4]

вывод элемента массива python (вывод элемента массива в python)

Проблема: зависимость от тяжёлой библиотеки, избыточно для простой задачи. Решение: использовать встроенные средства Python.

Как получить уникальные значения из списка с помощью NumPy?


import numpy as np
my_list = [3, 1, 2, 3, 1]
unique = np.unique(my_list).tolist()
print(unique)  # [1, 2, 3] (отсортировано)

Python списки добавление (добавление элемента в список python)

Проблема: результат всегда отсортирован, теряется исходный порядок. Требуется NumPy. Решение: использовать только если работа уже ведётся с NumPy массивами.

Как отфильтровать дубликаты с помощью itertools.groupby?


from itertools import groupby
my_list = [1, 1, 2, 3, 3, 4]
unique = [key for key, _ in groupby(sorted(my_list))]
print(unique)  # [1, 2, 3, 4]

Проблема: требуется предварительная сортировка (O(n log n)), теряется порядок. Решение: для простых задач лучше set.

- изменить элементы списка python (изменение элементов списка в python)
- Python list индекс элемента (индекс элемента в списке python)
- Python элементы списка в другой список (копирование элементов списка в другой список)

Расширенные примеры

Пример 1: Сравнение производительности разных методов

Пример

import time
import random

# Генерация списка с дубликатами
n = 100000
my_list = [random.randint(0, 50000) for _ in range(n)]

# Метод set
t0 = time.time()
res_set = list(set(my_list))
t_set = time.time() - t0

# Метод dict.fromkeys
t0 = time.time()
res_dict = list(dict.fromkeys(my_list))
t_dict = time.time() - t0

# Метод цикла с множеством
t0 = time.time()
seen = set()
res_loop = []
for x in my_list:
    if x not in seen:
        seen.add(x)
        res_loop.append(x)
t_loop = time.time() - t0

print(f"set: {t_set:.4f} сек, длина {len(res_set)}")
print(f"dict.fromkeys: {t_dict:.4f} сек, длина {len(res_dict)}")
print(f"loop+set: {t_loop:.4f} сек, длина {len(res_loop)}")
set: 0.0071 сек, длина 50107
dict.fromkeys: 0.0075 сек, длина 50107
loop+set: 0.0092 сек, длина 50107

Методы set и dict.fromkeys показывают близкую скорость, цикл с множеством чуть медленнее.

Пример 2: Работа с нехешируемыми элементами через кортежи

Пример

my_list = [[1,2], [3,4], [1,2], [5,6]]
seen = set()
unique = []
for item in my_list:
    t = tuple(item)
    if t not in seen:
        seen.add(t)
        unique.append(item)  # сохраняем исходный список, а не кортеж
print(unique)  # [[1, 2], [3, 4], [5, 6]]
[[1, 2], [3, 4], [5, 6]]

Пример 3: Сохранение порядка с помощью enumerate и словаря

Пример

my_list = [5, 1, 5, 3, 1, 2]
order = {}
for idx, val in enumerate(my_list):
    if val not in order:
        order[val] = idx
# Сортируем по индексу первого вхождения
unique_sorted_by_first = sorted(order.keys(), key=lambda x: order[x])
print(unique_sorted_by_first)  # [5, 1, 3, 2]
[5, 1, 3, 2]

Пример 4: Удаление дубликатов из списка строк с учётом регистра

Пример

my_list = ['Apple', 'apple', 'BANANA', 'banana', 'Apple']
# Без учёта регистра
seen = set()
unique = []
for s in my_list:
    lower = s.lower()
    if lower not in seen:
        seen.add(lower)
        unique.append(s)  # сохраняем исходное написание
print(unique)  # ['Apple', 'BANANA']
['Apple', 'BANANA']

Пример 5: Использование functools.reduce для уникализации

Пример

from functools import reduce

def add_unique(acc, x):
    if x not in acc['seen']:
        acc['seen'].add(x)
        acc['result'].append(x)
    return acc

my_list = [3, 1, 2, 3, 1, 4]
result = reduce(add_unique, my_list, {'seen': set(), 'result': []})
print(result['result'])  # [3, 1, 2, 4]
[3, 1, 2, 4]

Пример 6: Применение pd.unique для DataFrame

Пример

import pandas as pd
df = pd.DataFrame({'col1': [1,2,1,3,2], 'col2': ['a','b','a','c','b']})
unique_col1 = df['col1'].unique()
print(unique_col1)  # [1 2 3]
[1 2 3]

Получение уникальных значений из списка в Python - comments

En
Python уникальные значения в списке (python)