Программирование

Найти дублирующие целые числа в списке с Counter или Set

Узнайте, как извлечь дублирующие целые числа из списка в Python, используя collections.Counter или набор. Примеры кода практических советы по производительности.

Как можно найти дублирующиеся числа в списке целых и собрать их в отдельный список, где будут только повторяющиеся элементы?

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

Содержание

Нахождение дубликатов с помощью Counter

На самом деле, класс collections.Counter – удобный способ подсчитать вхождения каждого элемента.
После подсчёта любой элемент, чья частота превышает 1, считается дублирующим.

python
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.

Нахождение дубликатов с помощью множества

Если вы хотите избежать дополнительного прохода по данным, вы можете на самом деле обнаружить дубли во время одного прохода, используя множество для отслеживания уже увиденных элементов.

python
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 может действительно использовать чуть меньше памяти, поскольку он не хранит полный словарь счётов.
  • Для крайне больших входов, где память ограничена, рассмотрите потоковую обработку данных и выдачу дубликатов по мере их обнаружения (например, с помощью генераторов).

Распространённые крайние случаи

  1. Нет дубликатов – обе функции действительно вернут пустой список, что и ожидается.
  2. Все элементы дублируются – возвращаемый список будет содержать каждый уникальный элемент, что довольно просто.
  3. Нехешируемые элементы – если список содержит нехешируемые типы (например, списки), Counter всё равно работает, но метод на основе множества действительно вызовет TypeError. В таких случаях используйте Counter.
  4. Большие целые / отрицательные значения – оба метода одинаково обрабатывают целые числа, что довольно просто; специальной обработки не требуется.

Источники

  1. Python Documentation – collections.Counter
  2. Python Documentation – set
  3. Real Python: Using Counter in Python

Вывод

  • Для быстрого и читаемого решения действительно используйте collections.Counter и отфильтруйте счётчики, превышающие 1.
  • Для однопроходного, потенциально более экономного по памяти варианта, проходите с помощью множества, чтобы отслеживать уже увиденные элементы и собирать дубли – это довольно эффективно.
  • Оба метода работают за линейное время и действительно дают список уникальных дублирующих значений, готовый к дальнейшей обработке.
  • Выбирайте подход в зависимости от размера данных, ограничений памяти и того, появляются ли в списке нехешируемые элементы – это действительно важно.
Авторы
Проверено модерацией
Модерация