2016-12-07 5 views
3

Я думаю, что это простой вопрос, поэтому я просто перейду к примеру.Python: использование списков для фильтрации списка по списку подстрок

Учитывая эти два списка:

x = ['a', 'ab', 'abc', 'bc', 'c', 'ac'] 
y = ['a', 'b'] 

Как написать список понимание для фильтрации списка х таким образом, что результат будет:

result = ['c'] 

Я хочу список понимание, что исключает любые частичные совпадения строк в y с строками по x. Например, «a» в y будет соответствовать «a», «ab», «abc» и «ac» в x.

Это понимание соответствует только целые строки: result = [r for r in x if r not in y]

Если это уже был задан, я с удовольствием приму ссылку на предыдущий ответ. Тем не менее, я еще не нашел его на SO.

ответ

9

Использование all:

result = [r for r in x if all(z not in r for z in y)] 

Или any:

result = [r for r in x if not any(z in r for z in y)] 
+0

Это было все! У меня было какое-либо утверждение, но какие переменные z и r в вашем примере были бы отменены. Бонус: Я только что узнал о «все». Благодаря! – craignewkirk

2

Это работа для any встроенной.

>>> x = ['a', 'ab', 'abc', 'bc', 'c', 'ac'] 
>>> y = ['a', 'b'] 
>>> [r for r in x if not any(s in r for s in y)] 
['c'] 

s in r делает частичное совпадение вы хотите, for s in y проверяет все элементы y и any верно, если был любого матча. Затем мы просто инвертируем его.

Это квадратичный, O (len(x) * len(y)). Если y долго, это может быть более эффективным, чтобы синтезировать регулярное выражение:

>>> import re 
>>> yy = re.compile("|".join(re.escape(s) for s in y)) 
>>> [r for r in x if not yy.search(r)] 
['c'] 

, который должен быть просто O (len(x) + len(y)).

1

Это зависит от длины вашего y, что лучший подход, если он содержит много элементов, я бы преобразовал его в набор и проверил, есть ли у какого-либо элемента в x пересечение (один общий символ) с ним:

y = set(y) 
[item for item in x if not y.intersection(item)] 
+0

Предполагается, что 'y' содержит только строки длиной 1, что и в примере, но не указано. –

+0

Да, если в нем содержится больше символов, это, безусловно, не сработает, возможно, я взял пример OPs буквально. Но, с другой стороны, если 'y' содержит только отдельные буквы, это намного быстрее. :-) – MSeifert

+0

Да, в моем фактическом проекте это используется для фильтрации списка URL-адресов подстроками. – craignewkirk