Kuzunoha-NEのブログ

プログラミングなどの勉強をしてます

【Python】 値が文字列の中に含まれているか確認する。

こんばんは、葛の葉です。

さて、標題の件になりますが、ちょっと言葉だと説明しにくいかなと思います。例を挙げると

I Have a Dream.

Wikipediaより引用

ja.wikipedia.org

この中に特定の文字が入っていないかをBoolで返してもらう方法を書きます。

inを使う

例えばaという単語が入っているかを確認するには以下のようにします。

 'a' in 'I Have a Dream'

以下がコマンドラインPythonを実行したときの結果です。

>>> 'a' in 'I Have a Dream'
True
>>> 'b' in 'I Have a Dream'
False

Boolで返るのでassertも使えます。

>>> assert 'a' in 'I Have a Dream'
>>> assert 'b' in 'I Have a Dream'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

assert 'a' in 'I Have a Dream'は特に問題がないためTrueとなり、エラーなどは発生していません。一方、assert 'b' in 'I Have a Dream'はFalseとなるため、AssertionErrorとなっています。

listに入った複数の文字列が該当の文字列内に含まれているかの確認

例えば以下のように、IHaveaの文字全てが該当の文字列に含まれているかを確認したいとします。しかし、下記のようにリストをinとしてもTypeErrorが返されます。

>>> ['I', 'Have', 'a'] in 'I Have a Dream'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'in <string>' requires string as left operand, not list

リスト内包表記を使う

というわけでリスト内包表記を使いましょう。

False not in [i in 文字列 for i in 検索したい文字列の入ったリスト]

コマンドラインでは以下のようになります。

>>> False not in [i in 'I Have a Dream' for i in ['I', 'Have', 'a']]
True

分解するとFalse not in [リスト][i in 'I Have a Dream' for i in ['I', 'Have', 'a']]になると思います。

False not in [リスト]は最初にお話した'a' in 'I Have a Dream'の応用で、[list]の中にFalseが無ければTrueとなります。すなわち、リスト内が全てTrueだとTrueを返し、一つでもFalseがあればFalseを返します。ヤヤコシイネ。

>>> False not in [True,True,True,True]
True
>>> False not in [True,True,True,False]
False
>>> False not in [False,False,False,False]
False

さて、[i in 'I Have a Dream' for i in ['I', 'Have', 'a']]ですが、こちらは下部と同じ結果になります。

return_list = []
for i in ['I', 'Have', 'a']:
    result = i in 'I Have a Dream'
    return_list.append(result)

return_lisrt
[True, True, True]

結果は[True, True, True]となります。

すなわち、for文を用いて、含まれているか確認したい文字列が入ったリストの要素を一つずつとりだし、それぞれinを用いてBool値を返してもらい、それをリストの中に格納しています。

リスト内包表記での結果はこちら。

[i in 'I Have a Dream' for i in ['I', 'Have', 'a']]
[True, True, True]

含まれていない文字があればFalseがリストに返されます。

>>> [i in 'I Have a Dream' for i in ['I', 'king', 'a']]
[True, False, True] # kingの文字は存在しない

上記のFalse not inと組み合わせると

>>> False not in [i in 'I Have a Dream' for i in ['I', 'Have', 'a']]
True
>>> False not in [i in 'I Have a Dream' for i in ['I', 'king', 'a']]
False

と、このようになるわけです。

assertではこうです。

>>> assert False not in [i in 'I Have a Dream' for i in ['I', 'Have', 'a']]
>>> assert False not in [i in 'I Have a Dream' for i in ['I', 'king', 'a']]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

関数はこちら

def bool_check_words_in_word(check_words: list, the_word: str):
    # check_wordsには確認したい文字が含まれているリストを入れてください。
    # the_wordにはチェックしたい文字列を入れてください。
    return False not in [check_word in the_word for check_word in check_words]
print(
    bool_check_words_in_word(
        check_words=['I', 'Have', 'a'],
        the_word='I Have a Dream')
)

True