Найти дублирующие целые числа в списке с Counter или Set
Узнайте, как извлечь дублирующие целые числа из списка в Python, используя collections.Counter или набор. Примеры кода практических советы по производительности.
Как можно найти дублирующиеся числа в списке целых и собрать их в отдельный список, где будут только повторяющиеся элементы?
Вы можете быстро отделить все значения, которые встречаются более одного раза, используя встроенные коллекции Python.
Простой Counter на самом деле подсчитывает каждый элемент, а фильтрация счетчиков, превышающих 1, даёт вам дублирующие значения.
В качестве альтернативы, однопроходный подход с использованием множества может отслеживать впервые встреченные элементы и собирать дубли по мере их появления – довольно удобно.
Содержание
- Нахождение дубликатов с помощью Counter
- Нахождение дубликатов с помощью множества
- Производительность и требования к памяти
- Распространённые крайние случаи
Нахождение дубликатов с помощью Counter
На самом деле, класс collections.Counter – удобный способ подсчитать вхождения каждого элемента.
После подсчёта любой элемент, чья частота превышает 1, считается дублирующим.
from collections import Counter
def duplicates_counter(lst):
counts = Counter(lst)
return [item for item, n in counts.items() if n > 1]
# Example
numbers = [1, 2, 3, 2, 4, 5, 1, 6]
print(duplicates_counter(numbers)) # Output: [1, 2]
Почему это работает:
Counterсоздаёт словарь, где ключи – элементы списка, а значения – их частоты.- Список‑компрессия выбирает только те ключи, частота которых превышает 1.
Этот метод лаконичен и использует высоко оптимизированную реализацию Counter на C, поэтому он действительно быстрый и экономит память в типичных случаях.
Для более подробной информации см. официальную документацию Python по Counter:
Python Documentation – collections.Counter.
Нахождение дубликатов с помощью множества
Если вы хотите избежать дополнительного прохода по данным, вы можете на самом деле обнаружить дубли во время одного прохода, используя множество для отслеживания уже увиденных элементов.
def duplicates_set(lst):
seen = set()
duplicates = set()
for x in lst:
if x in seen:
duplicates.add(x)
else:
seen.add(x)
return list(duplicates)
# Example
numbers = [1, 2, 3, 2, 4, 5, 1, 6]
print(duplicates_set(numbers)) # Output: [1, 2]
Почему это работает:
- В первый раз элемент добавляется в
seen. - Повторные встречи распознаются тем, что элемент уже находится в
seen, поэтому он добавляется вduplicates. - Использование множества для
duplicatesгарантирует, что каждый дублирующий элемент появится только один раз в итоговом списке.
Этот подход использует два множества, но только один проход по исходному списку, что может быть действительно полезно при работе с очень большими потоками данных.
Для более подробной информации о множествах в Python см. официальную документацию:
Python Documentation – set.
Производительность и требования к памяти
| Подход | Сложность во времени | Сложность по памяти | Примечания |
|---|---|---|---|
Counter |
O(n) | O(k) – k = число различных элементов | Два прохода: подсчёт, затем фильтрация |
| Set pass | O(n) | O(k) – seen и duplicates |
Один проход; множество duplicates может быть меньше, чем seen |
- Для списков с большим количеством повторов метод
duplicates_setможет действительно использовать чуть меньше памяти, поскольку он не хранит полный словарь счётов. - Для крайне больших входов, где память ограничена, рассмотрите потоковую обработку данных и выдачу дубликатов по мере их обнаружения (например, с помощью генераторов).
Распространённые крайние случаи
- Нет дубликатов – обе функции действительно вернут пустой список, что и ожидается.
- Все элементы дублируются – возвращаемый список будет содержать каждый уникальный элемент, что довольно просто.
- Нехешируемые элементы – если список содержит нехешируемые типы (например, списки),
Counterвсё равно работает, но метод на основе множества действительно вызоветTypeError. В таких случаях используйтеCounter. - Большие целые / отрицательные значения – оба метода одинаково обрабатывают целые числа, что довольно просто; специальной обработки не требуется.
Источники
- Python Documentation – collections.Counter
- Python Documentation – set
- Real Python: Using Counter in Python
Вывод
- Для быстрого и читаемого решения действительно используйте
collections.Counterи отфильтруйте счётчики, превышающие 1. - Для однопроходного, потенциально более экономного по памяти варианта, проходите с помощью множества, чтобы отслеживать уже увиденные элементы и собирать дубли – это довольно эффективно.
- Оба метода работают за линейное время и действительно дают список уникальных дублирующих значений, готовый к дальнейшей обработке.
- Выбирайте подход в зависимости от размера данных, ограничений памяти и того, появляются ли в списке нехешируемые элементы – это действительно важно.