7 методов устранения повторяющихся элементов в списках Python

Опубликовано: 10.06.2025
Категория: Фишки
Теги: #Python
Просмотров: 992

В Python часто возникают ситуации, когда необходимо очистить список от дублирующихся значений, чтобы остались только неповторяющиеся, уникальные значения его элементов. В этой статье рассмотрим несколько эффективных подходов для решения этой задачи, и сравним их по скорости выполнения.

1. Прямой перебор значений

Определяем новый пустой список, затем в цикле идем по элементам списка, и если текущий элемент не содержится в новом списке, то добавляем его:


my_list = ["a", "a", "b", "a", "c", "c", "a", "b", "a",]

new_list = []
for item in my_list:
    if item not in new_list:
	    new_list.append(item)
print(new_list)    # Вывод: ["a", "b", "c"]

2. Использование множеств (set) для удаления дубликатов

Самый простой способ — преобразование списка в множество, а затем обратно в список:


original_elements = [10, 20, 30, 20, 40, 10, 50]
unique_items = list(set(original_elements))  
print(unique_items)  # Вывод: [40, 10, 50, 20, 30]

Важно: Порядок элементов не сохраняется, так как множества в Python неупорядочены.

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

Если порядок элементов важен, можно использовать словарь:


items = ["apple", "banana", "apple", "orange", "banana"]
filtered_list = list(dict.fromkeys(items))  
print(filtered_list)  # Вывод: ['apple', 'banana', 'orange']

4. Использование спискового включения (list comprehension)

Метод альтернативный первому — перебор элементов с проверкой на уникальность:


data = [1, 2, 2, 3, 4, 4, 5]
cleaned_data = []  
[cleaned_data.append(x) for x in data if x not in cleaned_data]  
print(cleaned_data)  # Вывод: [1, 2, 3, 4, 5]

5. С использованием enumerate():

Функция enumerate() перебирает элементы списка вместе с их индексами, предоставляя кортеж (index, element). Здесь n — это индекс, а i — значение элемента. Условие if i not in data[:n] проверяет, присутствует ли текущий элемент i среди всех предыдущих элементов (до позиции n включительно). Если он там отсутствует, элемент считается уникальным и включается в результирующий список. :


data = [1, 2, 2, 3, 4, 4, 5]
cleaned_data = []  
cleaned_data = [i for n, i in enumerate(data) if i not in data[:n]]  
print(cleaned_data)  # Вывод: [1, 2, 3, 4, 5]

6. Применение библиотеки Pandas

Для работы с большими массивами данных удобно использовать Pandas:


import pandas as pd

numbers = [5, 5, 10, 15, 10, 20]  
series = pd.Series(numbers)  
result = series.drop_duplicates().tolist()  
print(result)  # Вывод: [5, 10, 15, 20]

7. Применение OrderedDict из стандартного модуля collections

Можно использовать специальный класс collections.OrderedDict, представляющий собой словарь (dict), сохраняющий порядок вставки элементов:


from collections import OrderedDict as od

data_list = [3, 5, 1, 5, 3, 2]
cleaned_list = list(od.fromkeys(data_list))
print(cleaned_list)    # Вывод: [3, 5, 1, 2]

Скорость работы методов

Сравним скорость работы методов. Для этого используем стандартный модуль time и его метод time():


import random
import pandas as pd
from collections import OrderedDict as od
import time


# Генерируем список из 300000 случайных целых чисел от 1 до 10
data = [random.randint(1, 10) for _ in range(300000)]

start_time = time.time()
new_list = []
for item in data:
    if item not in new_list:
        new_list.append(item)
end_time = time.time()
execution_time = end_time - start_time
print(execution_time)

start_time = time.time()
unique_items = list(set(data))
end_time = time.time()
execution_time = end_time - start_time
print(execution_time)

start_time = time.time()
filtered_list = list(dict.fromkeys(data))
end_time = time.time()
execution_time = end_time - start_time
print(execution_time)

start_time = time.time()
cleaned_data = []
[cleaned_data.append(x) for x in data if x not in cleaned_data]
end_time = time.time()
execution_time = end_time - start_time
print(execution_time)

start_time = time.time()
cleaned_data = []
cleaned_data = [i for n, i in enumerate(data) if i not in data[:n]]
end_time = time.time()
execution_time = end_time - start_time
print(execution_time)

start_time = time.time()
series = pd.Series(data)
result = series.drop_duplicates().tolist()
end_time = time.time()
execution_time = end_time - start_time
print(execution_time)

start_time = time.time()
cleaned_list = list(od.fromkeys(data))
end_time = time.time()
execution_time = end_time - start_time
print(execution_time)

Результат выполнения программы:

0.09872746467590332
0.007032155990600586
0.010793924331665039
0.03624248504638672
203.83486247062683
0.2821784019470215
0.02706289291381836

Вывод

Выбор метода зависит от конкретной задачи. Для максимальной скорости подойдут множества (метод 2). Если важен порядок элементов в списке — используйте словари (метод 3) или OrderedDict (метод 7). Остальные методы подойдут для небольших массивов данных. Значительно хуже всех показал себя метод с использованием enumerate(). Он оригинален и работает для малых массивах, но скорость выполнения значительно возрастает при увеличении размера массива./p>