В Python есть несколько способов удалить дубликаты из списка, каждый из которых имеет свои преимущества и недостатки. Выбор оптимального способа зависит от ваших потребностей, таких как:
Сохранение порядка элементов: Нужно ли сохранить порядок элементов, как в исходном списке? Производительность: Насколько важна скорость выполнения операции, особенно для больших списков? Изменяемость: Нужно ли изменить исходный список или создать новый?
Вот основные способы:
1. Используя Set() (самый быстрый, но не сохраняет порядок):
Этот метод — самый быстрый и лаконичный, но он не сохраняет порядок элементов исходного списка. set — это неупорядоченная коллекция уникальных элементов.
My_list = [1, 2, 2, 3, 4, 4, 5, 1]
Unique_list = list(set(my_list))
Print(unique_list) # [1, 2, 3, 4, 5] (порядок может быть другим)
2. Используя OrderedDict. fromkeys() (сохраняет порядок, начиная с Python 3.7):
Начиная с Python 3.7, словари сохраняют порядок вставки элементов. OrderedDict все еще доступен в модуле collections для совместимости со старыми версиями Python, но его использование больше не является необходимым для сохранения порядка. Этот метод сохраняет порядок элементов и является достаточно эффективным.
My_list = [1, 2, 2, 3, 4, 4, 5, 1]
Unique_list = list(dict. fromkeys(my_list))
Print(unique_list) # [1, 2, 3, 4, 5] (порядок сохранен)
3. Используя цикл For и новый список (сохраняет порядок, менее эффективен):
Этот метод сохраняет порядок элементов, но он менее эффективен, особенно для больших списков, так как требует итерации по списку и проверки наличия каждого элемента в новом списке.
My_list = [1, 2, 2, 3, 4, 4, 5, 1]
Unique_list = []
For item in my_list:
if item not in unique_list:
unique_list. append(item)
Print(unique_list) # [1, 2, 3, 4, 5] (Порядок Сохранен)
4. Используя List Comprehension (сохраняет порядок, менее эффективен):
Это вариант предыдущего метода, записанный в более компактной форме с использованием List Comprehension. Он также сохраняет порядок элементов, но менее эффективен, чем использование set или dict. fromkeys().
My_list = [1, 2, 2, 3, 4, 4, 5, 1]
Unique_list = []
[unique_list. append(item) for item in my_list if item not in unique_list]
Print(unique_list) # [1, 2, 3, 4, 5]
5. Удаление дубликатов “на месте” (изменяет исходный список, сохраняет порядок, не самый эффективный):
Этот метод удаляет дубликаты непосредственно из исходного списка, изменяя его.
My_list = [1, 2, 2, 3, 4, 4, 5, 1]
I = 0
While i < len(my_list):
j = i + 1
while j < len(my_list):
if my_list[i] == my_list[j]:
del my_list[j]
else:
j += 1
i += 1
Print(my_list) # [1, 2, 3, 4, 5]
Этот метод Крайне не рекомендуется, так как он сложен в понимании, медленный и может привести к неожиданным результатам. Удаление элементов во время итерации по списку может нарушить индексы и привести к пропуску элементов.
6. Используя pandas (если у вас уже есть DataFrame):
Если ваши данные находятся в DataFrame pandas, вы можете использовать метод drop_duplicates().
Import pandas as pd
Data = {‘col1’: [1, 2, 2, 3, 4, 4, 5, 1]}
Df = pd. DataFrame(data)
Df_unique = df. drop_duplicates()
Unique_list = df_unique[‘col1’].tolist()
Print(unique_list) # [1, 2, 3, 4, 5] (порядок сохранен)
Производительность:
В общем случае, для больших списков:
set() (без сохранения порядка) — самый быстрый. dict. fromkeys() (сохраняет порядок) — достаточно быстрый и обычно предпочтительный. Циклы for и List Comprehensions — менее эффективны. Удаление “на месте” — крайне неэффективно.
Какой метод выбрать?
Если порядок не важен и нужна максимальная скорость: Используйте set(). Если порядок важен и нужна хорошая производительность: Используйте dict. fromkeys(). Это наиболее рекомендуемый способ в большинстве случаев. Если у вас небольшой список, или вы хотите более явно контролировать процесс (хотя это и менее эффективно), можно использовать цикл for или List Comprehension. Никогда не используйте удаление “на месте” (метод 5). Если ваши данные находятся в DataFrame pandas, используйте drop_duplicates().
Пример выбора метода в зависимости от размера списка и требований к порядку:
Import time
Def remove_duplicates_set(data):
return list(set(data))
Def remove_duplicates_ordered_dict(data):
return list(dict. fromkeys(data))
Def remove_duplicates_loop(data):
unique_list = []
for item in data:
if item not in unique_list:
unique_list. append(item)
return unique_list
# Создаем большой список с дубликатами
List_size = 10000
My_list = [random. randint(0, list_size // 10) for _ in range(list_size)] # Много Дубликатов
# Проверяем время выполнения для разных методов
Start_time = time. time()
Unique_list_set = remove_duplicates_set(my_list)
End_time = time. time()
Print(f"Set: {end_time — start_time:.4f} seconds, size: {len(unique_list_set)}")
Start_time = time. time()
Unique_list_ordered_dict = remove_duplicates_ordered_dict(my_list)
End_time = time. time()
Print(f"OrderedDict: {end_time — start_time:.4f} seconds, size: {len(unique_list_ordered_dict)}")
Start_time = time. time()
Unique_list_loop = remove_duplicates_loop(my_list)
End_time = time. time()
Print(f"Loop: {end_time — start_time:.4f} seconds, size: {len(unique_list_loop)}")
# Проверяем, что результаты одинаковы (если порядок не важен)
Print(f"Set and OrderedDict results are the same: {set(unique_list_set) == set(unique_list_ordered_dict)}")
Import random
Результаты этого кода покажут, что set и dict. fromkeys() значительно быстрее цикла for, особенно для больших списков.