Предполагая список следующим образом:
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
но оба кода не работают.
Может кто-нибудь, пожалуйста, скажите мне, какую ошибку я делаю?
Спасибо
Логически ваша проблема заключается в сравнении набор символов в слове, которое нужно найти, с набор символов в каждом слове в списке. Если последнее слово содержит все символы искомого слова, то это совпадение. Вот один из подходов, использующий понимание списка вместе с набором 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 ... и ОП явно хочет совпадений в порядке Любые.
Хм ... Я понял любой порядок to_find, но все же подстроку (буквы to_find должны быть рядом друг с другом), поскольку OP часто использовал слово «подстрока». Но, похоже, ОП сказал, что «поскольку в to_find есть все буквы», поэтому ваше решение соответствует этому...
[w for w in l if to_find_set.issubset(w)]
@TimBiegeleisen Спасибо за помощь. Только один вопрос: если нет доступных строк, соответствующих to_find
, как я могу вернуть пустую строку?
@reinhardt Проверьте обновленный ответ выше.
Вам нужно, чтобы буквы 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
будет большим? Любое альтернативное решение для улучшения временной сложности?
Набор будет соответствовать и не по порядку. Нравится "сиабдо"