別の文字列に複数の文字列が存在するかどうかを確認します


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
コンパイルされた正規表現と比較して、特に文字列のサイズと検索する「針」の数と比較して、パフォーマンスに関するコンパイル済みの正規表現と比較して(まだ)回答がないことに驚きます。
Pat

3
@Pat私は驚いていない。問題はパフォーマンスについてではありません。今日ほとんどのプログラマーはそれを成し遂げることと読みやすさをもっと重視しています。パフォーマンスの質問は有効ですが、別の質問です。
guettli 2016

13
strを変数として使用すると混乱を招き、予約語であるため予期しない動作が発生する可能性があります。リンクを参照してください
賢い人

正規表現[abc]も完璧に機能し、テストする候補が2つ以上ある場合は高速になります。しかし、文字列が任意であり、正規表現を構築するためにそれらを事前に知らない場合は、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
any()はイテラブルを取ります。使用しているPythonのバージョンはわかりませんが、2.6では、any()の引数を[]で囲む必要があります。any([x in str for x in a])内包表記が反復可能を返すようにします。しかし、多分それ以降のバージョンのPythonはすでにこれを行っています。
emispowder 2013年

7
@Mark Byers:最近のコメントは申し訳ありませんが、見つかった文字列を出力する方法はありますか?どうしますか ありがとうございました。
Shankar Kumar 2013

3
よくわかりません。aがリストで、strが照合対象の場合、xは何ですか?Python初心者ftw。:)

2
@red:for x in a「リスト内の各要素」のように読み取ることができます。ので、a文字列のリストであり、xそのリストの要素であり、x文字列(元の例で'、「B」、「C」の1つ)である
ユーザー

6
@emispowder Python 2.6.9では、そのままで問題なく動作します。
MPlanchard、2015

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)

最後の試合の例も追加してください
Oleg Kokorin

@OlegKokorin:一致する文字列のリストを、見つかったのと同じ順序で作成しますが、2つが同じ場合は最初の文字列のみを保持します。
zondo 2018

を使用するOrderedDictと、リストよりもパフォーマンスが向上します。「リスト内の重複の削除」でこの回答を
wjandrea

44

内の文字列場合は、注意しなければならないaかがstr長くなります。簡単な解決策はO(S *(A ^ 2))を取ります。ここで、Sはの長さでstrあり、Aはのすべての文字列の長さの合計ですa。より高速なソリューションについては、線形時間O(S + A)で実行される文字列マッチングのAho-Corasickアルゴリズムをご覧ください。


Aho-Corasickはプレフィックスの代わりに部分文字列も見つけることができますか?
RetroCode、2016

1
いくつかのPython Aho-Corasickライブラリがここここに
vorpal '27 / 09/27

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 2017年

12

aの要素を反復する必要があります。

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
マークのコードを理解している場合のみ。あなたが抱えていた問題は、配列の要素を調べていなかったことです。あなたが望むものを達成するための簡潔でPython的な方法はたくさんありますが、それはあなたのコードの何が悪いのかという本質を隠すでしょう。
Seamus Campbell

9
「恐ろしいコード」かもしれませんが、それはまさにany()が行うことです。また、これは一致した実際の文字列を提供しますが、any()は一致があることを通知するだけです。
alldayremix 2013

4

jbernadasはすでにAho-Corasick-Algorithmについて言及しました複雑さを軽減するためににます。

Pythonで使用する1つの方法を次に示します。

  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

それはあなたがのような単一のリテラルをチェックしたい場合は状況に依存します(任意の単一の単語a、e、w、.. etc)十分です

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")

あなたの入力は何でしょうか?私は2つのことを認識できます。何かを探している文です。私が探している単語の配列。しかし、あなたは3つの変数を記述し、私は3番目の変数が何であるかわかりません。
Mayid

1

文字列で利用可能なすべてのリスト要素を取得する方法に関するいくつかの詳細情報

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)));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.