Самый быстрый способ, но не сохраняет порядок элементов:
original = [3, 1, 2, 2, 4, 3, 1]
unique = list(set(original))
print(unique) # Может получиться [1, 2, 3, 4] (порядок не гарантирован)
Используем словарь для сохранения порядка:
from collections import OrderedDict
original = [3, 1, 2, 2, 4, 3, 1]
unique = list(OrderedDict.fromkeys(original))
print(unique) # [3, 1, 2, 4] (порядок сохранен)
Медленнее, но сохраняет порядок и понятен:
original = [3, 1, 2, 2, 4, 3, 1]
unique = []
[unique.append(x) for x in original if x not in unique]
print(unique) # [3, 1, 2, 4]
Простой способ с сохранением порядка:
original = [3, 1, 2, 2, 4, 3, 1]
unique = list(dict.fromkeys(original))
print(unique) # [3, 1, 2, 4]
Полезно для отсортированных списков:
from itertools import groupby
original = [1, 1, 2, 2, 3, 4, 4]
unique = [k for k, _ in groupby(sorted(original))]
print(unique) # [1, 2, 3, 4]
Для работы с большими данными:
import pandas as pd
original = [3, 1, 2, 2, 4, 3, 1]
unique = pd.unique(original).tolist()
print(unique) # [3, 1, 2, 4] (порядок сохранен)
from timeit import timeit
setup = "original = [3, 1, 2, 2, 4, 3, 1] * 1000"
methods = {
"set": "list(set(original))",
"OrderedDict": "list(OrderedDict.fromkeys(original))",
"dict": "list(dict.fromkeys(original))",
"list comp": "[x for i, x in enumerate(original) if x not in original[:i]]"
}
for name, code in methods.items():
time = timeit(code, setup, number=1000, globals=globals())
print(f"{name:10}: {time:.5f} sec")
Результаты (чем меньше время, тем лучше):
set
: самый быстрый, но без сохранения порядкаdict
/OrderedDict
: немного медленнее, но сохраняют порядокЕсли элементы списка - словари или списки:
original = [{'a': 1}, {'b': 2}, {'a': 1}]
# Способ 1: через сравнение словарей
unique = []
for item in original:
if item not in unique:
unique.append(item)
# Способ 2: через сериализацию в строку
unique = [eval(x) for x in set([str(x) for x in original])]
Например, оставить последнее вхождение:
original = [3, 1, 2, 2, 4, 3, 1]
unique = list({x: i for i, x in enumerate(original)}.keys())
print(unique) # [2, 4, 3, 1]
Для простых случаев (нетребовательность к порядку):
list(set(original))
- самый быстрый способС сохранением порядка:
list(dict.fromkeys(original))
(Python 3.7+)list(OrderedDict.fromkeys(original))
(все версии Python)Для сложных объектов:
not in
Для больших данных:
pandas.unique()
может быть эффективнееВыбор метода зависит от: