Как найти строку, которая соответствует подстроке в любом порядке?

Предполагая список следующим образом:

list_of_strings = ['foo', 'bar', 'soap', 'seo', 'paseo', 'oes']

и подстрока

to_find = 'eos'

Я хотел бы найти строку (строки) в list_of_strings, которые соответствуют подстроке. Вывод из list_of_strings должен быть ['seo', 'paseo', 'oes'] (поскольку он содержит все буквы в подстроке to_find)

Я попробовал пару вещей:

a = next((string for string in list_of_strings if to_find in string), None) # gives NoneType object as output

&

result = [string for string in list_of_strings if to_find in string] # gives [] as output

но оба кода не работают.

Может кто-нибудь, пожалуйста, скажите мне, какую ошибку я делаю?

Спасибо

Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
1
0
31
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Логически ваша проблема заключается в сравнении набор символов в слове, которое нужно найти, с набор символов в каждом слове в списке. Если последнее слово содержит все символы искомого слова, то это совпадение. Вот один из подходов, использующий понимание списка вместе с набором intesection:

list_of_strings = ['foo', 'bar', 'soap', 'seo', 'paseo', 'oes']
to_find = 'eos'
to_find_set = set(list(to_find))
output = [x for x in list_of_strings if len(to_find_set.intersection(set(list(x)))) == len(to_find_set)]
print(output)  # ['seo', 'paseo', 'oes']

Если вы хотите сохранить пустую строку-заполнитель для любой входной строки, которая соответствует нет, используйте эту версию:

output = [x if len(to_find_set.intersection(set(list(x)))) == len(to_find_set) else '' for x in list_of_strings]
print(output)  # ['', '', '', 'seo', 'paseo', 'oes']

Набор будет соответствовать и не по порядку. Нравится "сиабдо"

h4z3 17.05.2022 11:05

@ h4z3 ... и ОП явно хочет совпадений в порядке Любые.

Tim Biegeleisen 17.05.2022 11:06

Хм ... Я понял любой порядок to_find, но все же подстроку (буквы to_find должны быть рядом друг с другом), поскольку OP часто использовал слово «подстрока». Но, похоже, ОП сказал, что «поскольку в to_find есть все буквы», поэтому ваше решение соответствует этому...

h4z3 17.05.2022 11:12
[w for w in l if to_find_set.issubset(w)]
gboffi 17.05.2022 11:48

@TimBiegeleisen Спасибо за помощь. Только один вопрос: если нет доступных строк, соответствующих to_find, как я могу вернуть пустую строку?

reinhardt 17.05.2022 11:54

@reinhardt Проверьте обновленный ответ выше.

Tim Biegeleisen 17.05.2022 11:57

Вам нужно, чтобы буквы to_find были рядом друг с другом или просто все буквы должны быть в слове? В основном: соответствует ли seabco или нет?

[Ваш вопрос не включает эту деталь, и вы часто используете «подстроку», но также «поскольку в ней есть все буквы в to_find», поэтому я не уверен, как это интерпретировать.]

Если seabco совпадает, то ответ @Tim Biegeleisen является правильным. Если буквы должны стоять рядом (но в любом порядке, конечно), то смотрим ниже:


Если to_find относительно короткий, вы можете просто сгенерировать все перестановки букв (n! из них, так что здесь (3!) = 6: eos, eso, oes, ose, seo, soe) и проверить in.

import itertools
list_of_strings = ['foo', 'bar', 'soap', 'seo', 'paseo', 'oes']
to_find = 'eos'

result = [string for string in list_of_strings if any("".join(perm) in string for perm in itertools.permutations(to_find))]

https://docs.python.org/3/library/itertools.html#itertools.permutations

Мы делаем "".join(perm), потому что perm — это кортеж, и нам нужна строка.

>>> result = [string for string in list_of_strings if any("".join(perm) in string for perm in itertools.permutations(to_find))]
>>> result
['seo', 'paseo', 'oes']

Что произойдет, если to_find будет большим? Любое альтернативное решение для улучшения временной сложности?

reinhardt 17.05.2022 18:12

Другие вопросы по теме