← Назад к вопросам

Как сделать пересечение массивов в Python?

1.0 Junior🔥 191 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как сделать пересечение массивов в Python

Пересечение массивов (set intersection) — это операция поиска общих элементов в двух или более массивах/списках. В Python есть несколько способов реализации с разными характеристиками производительности.

Вариант 1: Использование set

Самый эффективный и pythonic способ:

arr1 = [1, 2, 3, 4, 5]
arr2 = [3, 4, 5, 6, 7]

# Способ 1: оператор &
intersection = set(arr1) & set(arr2)
print(intersection)  # {3, 4, 5}

# Способ 2: метод intersection()
intersection = set(arr1).intersection(set(arr2))
print(intersection)  # {3, 4, 5}

# Способ 3: метод intersection() с распаковкой
intersection = set(arr1).intersection(arr2)  # arr2 может быть списком
print(intersection)  # {3, 4, 5}

Сложность: O(n + m), где n и m — размеры массивов.

Вариант 2: Несколько массивов

arr1 = [1, 2, 3, 4, 5]
arr2 = [3, 4, 5, 6, 7]
arr3 = [4, 5, 8, 9, 10]

# Пересечение всех трёх
intersection = set(arr1) & set(arr2) & set(arr3)
print(intersection)  # {4, 5}

# Или через метод
intersection = set(arr1).intersection(arr2, arr3)
print(intersection)  # {4, 5}

# С переменным числом массивов
arrays = [arr1, arr2, arr3]
intersection = set(arrays[0])
for arr in arrays[1:]:
    intersection &= set(arr)
print(intersection)  # {4, 5}

# Или более elegantly
intersection = set.intersection(*[set(arr) for arr in arrays])
print(intersection)  # {4, 5}

Вариант 3: С сохранением порядка

Set не сохраняет порядок. Если нужно сохранить порядок из первого массива:

arr1 = [1, 2, 3, 4, 5]
arr2 = [5, 4, 3, 6, 7]

# Способ 1: list comprehension
intersection = [x for x in arr1 if x in arr2]
print(intersection)  # [3, 4, 5]

# Способ 2: более эффективно с set
set_arr2 = set(arr2)
intersection = [x for x in arr1 if x in set_arr2]
print(intersection)  # [3, 4, 5] — быстрее!

# Способ 3: filter
intersection = list(filter(lambda x: x in set(arr2), arr1))
print(intersection)  # [3, 4, 5]

Сложность: O(n + m) вместо O(n*m) с проверкой в списке.

Вариант 4: Отсортированные массивы (два указателя)

Если массивы уже отсортированы, можно использовать алгоритм двух указателей:

def intersection_sorted(arr1, arr2):
    """Пересечение двух отсортированных массивов"""
    result = []
    i, j = 0, 0
    
    while i < len(arr1) and j < len(arr2):
        if arr1[i] == arr2[j]:
            result.append(arr1[i])
            i += 1
            j += 1
        elif arr1[i] < arr2[j]:
            i += 1
        else:
            j += 1
    
    return result

arr1 = [1, 2, 3, 4, 5]
arr2 = [3, 4, 5, 6, 7]
print(intersection_sorted(arr1, arr2))  # [3, 4, 5]

Сложность: O(n + m) — очень эффективно для отсортированных данных!

Вариант 5: Обработка дубликатов

Если нужно сохранить все дубликаты:

from collections import Counter

arr1 = [1, 2, 2, 3, 3, 3, 4, 5]
arr2 = [2, 3, 3, 4, 4, 5, 6]

# Способ 1: с дубликатами как в меньшем массиве
counter1 = Counter(arr1)
counter2 = Counter(arr2)

intersection = []
for num in counter1:
    if num in counter2:
        # Берём минимальное количество
        count = min(counter1[num], counter2[num])
        intersection.extend([num] * count)

print(sorted(intersection))  # [2, 3, 3, 4, 5]

# Способ 2: используя Counter.intersection
intersection_counter = counter1 & counter2
intersection = list(intersection_counter.elements())
print(sorted(intersection))  # [2, 3, 3, 4, 5]

Вариант 6: NumPy для больших массивов

Для больших численных массивов:

import numpy as np

arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([3, 4, 5, 6, 7])

intersection = np.intersect1d(arr1, arr2)
print(intersection)  # [3 4 5]

Характеристики:

  • Быстро для больших массивов (написано на C)
  • Автоматически удаляет дубликаты и сортирует
  • Гибкость с параметром assume_unique

Сравнение производительности

import time
import numpy as np

# Создать большие массивы
arr1 = list(range(0, 1000000, 2))  # 500,000 элементов
arr2 = list(range(500000, 1500000, 2))  # 500,000 элементов

# Метод 1: set
start = time.time()
result1 = set(arr1) & set(arr2)
time1 = time.time() - start
print(f"Set method: {time1:.4f}s")

# Метод 2: list comprehension
start = time.time()
set_arr2 = set(arr2)
result2 = [x for x in arr1 if x in set_arr2]
time2 = time.time() - start
print(f"List comprehension: {time2:.4f}s")

# Метод 3: NumPy
start = time.time()
result3 = np.intersect1d(arr1, arr2)
time3 = time.time() - start
print(f"NumPy: {time3:.4f}s")

# Результат: NumPy обычно быстрее для больших данных

Практический пример: поиск общих друзей

class User:
    def __init__(self, name, friends):
        self.name = name
        self.friends = set(friends)
    
    def common_friends(self, other_user):
        """Найти общих друзей"""
        return self.friends & other_user.friends
    
    def common_friends_with_multiple(self, users):
        """Найти общих друзей со всеми пользователями"""
        common = self.friends
        for user in users:
            common &= user.friends
        return common

alice = User("Alice", ["Bob", "Charlie", "David", "Eve"])
bob = User("Bob", ["Alice", "Charlie", "Frank"])
charlie = User("Charlie", ["Alice", "Bob", "Grace"])

print(alice.common_friends(bob))  # {'Charlie'}
print(alice.common_friends_with_multiple([bob, charlie]))  # {'Charlie'}

Оптимизация для больших наборов данных

def efficient_intersection(arrays):
    """Оптимизированное пересечение нескольких массивов"""
    if not arrays:
        return []
    
    # Найти самый маленький массив
    min_array = min(arrays, key=len)
    other_arrays = [set(arr) for arr in arrays if arr is not min_array]
    
    # Проверять только элементы из самого маленького
    result = []
    for item in min_array:
        if all(item in arr for arr in other_arrays):
            result.append(item)
    
    return result

arr1 = [1, 2, 3, 4, 5]
arr2 = [3, 4, 5, 6, 7]
arr3 = [4, 5, 8, 9, 10]

print(efficient_intersection([arr1, arr2, arr3]))  # [4, 5]

Типичные ошибки

# ❌ Неправильно: медленно для больших данных
arr1 = range(1000000)
arr2 = range(500000, 1500000)
intersection = [x for x in arr1 if x in arr2]  # O(n*m)!

# ✅ Правильно: быстро
arr2_set = set(arr2)
intersection = [x for x in arr1 if x in arr2_set]  # O(n + m)

# ❌ Неправильно: потеря порядка не требуется
intersection = sorted(set(arr1) & set(arr2))  # Лишняя сортировка

# ✅ Правильно: если порядок не важен
intersection = set(arr1) & set(arr2)

Заключение

Пересечение массивов в Python:

  • Set операции (&, intersection()) — быстро и просто
  • List comprehension с set — сохраняет порядок
  • Двойной указатель для отсортированных массивов
  • Counter для сохранения дубликатов
  • NumPy для больших численных массивов
  • Оптимизация: проверять маленький массив против больших
  • Сложность: избегать O(n*m), стремиться к O(n + m)
Как сделать пересечение массивов в Python? | PrepBro