Перевірте, чи існує кілька рядків в іншій рядку


378

Як я можу перевірити, чи існує будь-який з рядків масиву в іншому рядку?

Подібно до:

a = ['a', 'b', 'c']
str = "a123"
if a in str:
  print "some of the strings found in str"
else:
  print "no strings found in str"

Цей код не працює, це просто показати, чого я хочу досягти.


5
Я здивований, що немає (поки що) жодних відповідей у ​​порівнянні зі складеним регулярним виразом з точки зору perf, особливо порівняно з розміром рядка та кількістю «голок» для пошуку.
— Пт

3
@Pat Я не здивований. Питання не в продуктивності. Сьогодні більшість програмістів більше піклуються про те, щоб зробити це і читати. Питання про виконання дійсне, але питання інше.
— guettli

13
Використання str як змінної є заплутаним і може спричинити несподівану поведінку, оскільки це зарезервоване слово; див. посилання .
— Розумний Гай

Регекс [abc]також працює чудово і буде швидшим, якщо для тестування буде більше ніж кілька кандидатів. Але якщо рядки є довільними і ви не знаєте їх заздалегідь, щоб побудувати регулярний вираз, вам доведеться використовувати any(x in str for x in a)підхід.
— smci

@CleverGuy Ви маєте рацію, хоча це не зарезервоване слово, інакше ви не зможете призначити його. Це вбудований.
— wjandrea

Відповіді:


717

Ви можете використовувати any:

a_string = "A string is more than its parts!"
matches = ["more", "wholesome", "milk"]

if any(x in a_string for x in matches):

Аналогічно, щоб перевірити, чи знайдені всі рядки зі списку, використовуйте allзамість any.


11
будь-який () приймає ітерабельний. Я не впевнений, яку версію Python ви використовуєте, але в 2.6 вам потрібно буде поставити [] навколо свого аргументу до будь-якого (). будь-який ([x in str for x in a]), так що розуміння повертає ітерабельний. Але, можливо, пізніші версії Python вже роблять це.
— випромінювач

7
@Mark Byers: Вибачте за пізній коментар, але чи є спосіб надрукувати знайдений рядок? Як би ти це зробив. Дякую.
— Шанкар Кумар

3
Не впевнений, що я розумію, якщо a - це список, а str - це річ, з якою потрібно відповідати, що таке x? Python newbie ftw. :)
— червоний

2
@red: ви можете прочитати на for x in aзразок "для кожного елемента в списку". Так aяк це список рядків і xє елементом цього списку, xце рядок (один із 'a', 'b', 'c' в оригінальному прикладі)
— Користувач

6
@emispowder Це добре працює для мене, як є в Python 2.6.9.
— MPlanchard

67

any()на сьогоднішній день є найкращим підходом , якщо все , що ви хочете, Trueабо False, але якщо ви хочете знати , в зокрема , які відповідає рядку / рядок, ви можете використовувати пару речей.

Якщо ви хочете першу відповідність ( Falseза замовчуванням):

match = next((x for x in a if x in str), False)

Якщо ви хочете отримати всі збіги (включаючи дублікати):

matches = [x for x in a if x in str]

Якщо ви хочете отримати всі не повторювані збіги (не зважаючи на порядок):

matches = {x for x in a if x in str}

Якщо ви хочете отримати всі неповторні збіги у потрібному порядку:

matches = []
for x in a:
    if x in str and x not in matches:
        matches.append(x)

будь ласка, додайте приклад і для останнього матчу
— Олег Кокорін

@OlegKokorin: Він створює список відповідних рядків у тому самому порядку, коли він їх знаходить, але він зберігає лише перший, якщо два однакові.
— zondo

Використання атрибуту OrderedDict, ймовірно, більш ефективне, ніж список. Дивіться цю відповідь на тему "Видалення дублікатів у списках"
— wjandrea

44

Ви повинні бути обережними, якщо струни в них aабо strдовші. Безпосередні розв'язки приймають O (S * (A ^ 2)), де Sдовжина strі A - сума довжин усіх рядків a. Для швидшого вирішення, подивіться алгоритм Aho-Corasick для відповідності рядків, який працює в лінійний час O (S + A).


Чи може Aho-Corasick також знайти підрядки замість префіксів?
— RetroCode

1
Деякі бібліотеки пітона Aho-Corasick є тут і тут
— vorpal

23

Просто для додання певного різноманіття regex:

import re

if any(re.findall(r'a|b|c', str, re.IGNORECASE)):
    print 'possible matches thanks to regex'
else:
    print 'no matches'

або якщо ваш список занадто довгий - any(re.findall(r'|'.join(a), str, re.IGNORECASE))


1
Це працює для даного випадку використання питання. Якщо пошук, який ви шукаєте, (або *це не вдається, оскільки потрібно виконати цитування синтаксису регулярних виразів.
— guettli

2
Ви можете уникнути цього, якщо це необхідно '|'.join(map(re.escape, strings_to_match)). Ви, мабуть, re.compile('|'.join(...))також можете.
— Artyer

12

Потрібно перебрати елементи а.

a = ['a', 'b', 'c']
str = "a123"
found_a_string = False
for item in a:    
    if item in str:
        found_a_string = True

if found_a_string:
    print "found a match"
else:
    print "no match found"

2
Так, я знав, як це зробити, але порівняно з відповіддю Маркса, це жахливий код.
— jahmax

10
Тільки якщо ви розумієте код Марка. Проблема, яку ви мали, полягає в тому, що ви не вивчали елементи свого масиву. Існує багато хитромудрих, пітонічних способів досягти того, що ви хочете, що приховувало б суть того, що було не так у вашому коді.
— Seamus Campbell

9
Це може бути "жахливий код", але це саме те, що робить будь-який () . Крім того, це дає вам фактичну відповідність рядка, тоді як будь-який () просто говорить вам про збіг.
— alldayremix

4

jbernadas вже згадував алгоритм Ахо-Корасика з метою зменшення складності.

Ось один із способів його використання в Python:

  1. Завантажте aho_corasick.py звідси

  2. Помістіть його в той самий каталог, що і ваш основний файл Python, і дайте ім’я aho_corasick.py

  3. Спробуйте алгоритм із наступним кодом:

    from aho_corasick import aho_corasick #(string, keywords)
    
    print(aho_corasick(string, ["keyword1", "keyword2"]))

Зауважте, що пошук залежить від регістру


3
a = ['a', 'b', 'c']
str =  "a123"

a_match = [True for match in a if match in str]

if True in a_match:
  print "some of the strings found in str"
else:
  print "no strings found in str"

1

Це залежить від контексту , припустимо , якщо ви хочете , щоб перевірити одного Літерал як (будь одне слово а, е, ж, .. і т.д.) в досить

original_word ="hackerearcth"
for 'h' in original_word:
      print("YES")

якщо ви хочете перевірити будь-який символ серед original_word: скористайтеся

if any(your_required in yourinput for your_required in original_word ):

якщо ви хочете, щоб весь вхід, який ви хочете, в цьому original_word, скористайтеся всім простим

original_word = ['h', 'a', 'c', 'k', 'e', 'r', 'e', 'a', 'r', 't', 'h']
yourinput = str(input()).lower()
if all(requested_word in yourinput for requested_word in original_word):
    print("yes")

Який би був ваш вхід? Я можу розпізнати дві речі: речення, де я щось шукаю. Я шукаю масив слів. Але ви описуєте три змінні, і я не можу отримати те, що є третім.
— mayid

1

Ще трохи інформації про те, як отримати всі елементи списку, доступні в String

a = ['a', 'b', 'c']
str = "a123" 
list(filter(lambda x:  x in str, a))

1

Напрочуд швидкий підхід полягає у використанні set:

a = ['a', 'b', 'c']
str = "a123"
if set(a) & set(str):
    print("some of the strings found in str")
else:
    print("no strings found in str")

Це працює, якщо aне містить знаків з декількома символами (у цьому випадку використовуйте, anyяк зазначено вище ). Якщо це так, то простіше вказати aу вигляді рядка: a = 'abc'.


0
flog = open('test.txt', 'r')
flogLines = flog.readlines()
strlist = ['SUCCESS', 'Done','SUCCESSFUL']
res = False
for line in flogLines:
     for fstr in strlist:
         if line.find(fstr) != -1:
            print('found') 
            res = True


if res:
    print('res true')
else: 
    print('res false')

вихідний приклад зображення


0

Я використовував би цю функцію для швидкості:

def check_string(string, substring_list):
    for substring in substring_list:
        if substring in string:
            return True
    return False

0
data = "firstName and favoriteFood"
mandatory_fields = ['firstName', 'lastName', 'age']


# for each
for field in mandatory_fields:
    if field not in data:
        print("Error, missing req field {0}".format(field));

# still fine, multiple if statements
if ('firstName' not in data or 
    'lastName' not in data or
    'age' not in data):
    print("Error, missing a req field");

# not very readable, list comprehension
missing_fields = [x for x in mandatory_fields if x not in data]
if (len(missing_fields)>0):
    print("Error, missing fields {0}".format(", ".join(missing_fields)));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.