Как оптимально удалить элементы массива содержащие элементы другого массива?

Подскажите, как оптимально удалить элементы массива, содержащие элементы другого массива?

Есть 2 массива:

arr1 = ['hello', 'world', 'test', 'lalala']
arr2 = ['el', 'es']

Мне нужно получить массив: ['world', 'lalala'].


Ответы (3 шт):

Автор решения: strawdog
res = [x for x in arr1 if not any([x.find(y)>=0 for y in arr2])]
print(res)

['world', 'lalala']

UPDATE

более простой и быстрый, но чуть менее универсальный вариант от CrazyElf

res = [x for x in arr1 if not any(y in x for y in arr2)]
→ Ссылка
Автор решения: mazzz3r

В самом плохом случае все равно придется для каждого элемента массива arr1 проходиться по всему массиву arr2, но можно сократить время с помощью остановки второго цикла, если произошло совпадение. Выглядит это примерно так:

answer = []
for i in arr1:
    match = False
    for j in arr2:
        if j in i:
            match = True
            break # Вот здесь мы перестаем перебирать массив arr2, ибо уже есть совпадение
    if not match:
        answer.append(i)
print(answer)

→ Ссылка
Автор решения: SergFSM

поскольку элементы списков - это строки, то почему бы не попробовать регулярку:

from re import search

res = list(filter(lambda x: not search(fr'{"|".join(arr2)}', x), arr1))

правда по времени это решение проигрывает решению от strawdog:

10.4 µs ± 44.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

против:

5.67 µs ± 79.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

но самое быстрое оказалось решение от mazzz3r:

1.61 µs ± 4.86 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

p.s. тест времени проводился на примере из вопроса.

→ Ссылка