文字列にPythonのリストの要素が含まれているかどうかを確認する方法


217

私はこのようなものを持っています:

extensionsToCheck = ['.pdf', '.doc', '.xls']

for extension in extensionsToCheck:
    if extension in url_string:
        print(url_string)

これをPythonで(forループを使用せずに)よりエレガントな方法は何でしょうか?私はこのようなもの(C / C ++など)を考えていましたが、うまくいきませんでした。

if ('.pdf' or '.doc' or '.xls') in url_string:
    print(url_string)

編集:私はこれが重複の可能性があるとマークされている以下の質問とどのように異なるかを説明することを余儀なくされています(したがって、私はおそらく閉じられません)。

違いは、文字列が文字列のリストの一部であるかどうかを確認したかったのに対し、他の質問は、文字列のリストからの文字列が別の文字列の部分文字列であるかどうかを確認することです。同様ですが、まったく同じではありません。オンラインのIMHOで回答を探している場合、セマンティクスは重要です。これら2つの質問は、実際には互いに反対の問題を解決することを目的としています。ただし、両方のソリューションは同じです。


回答:


418

と一緒にジェネレータを使用しanyます。最初のTrueで短絡します。

if any(ext in url_string for ext in extensionsToCheck):
    print(url_string)

編集:この回答はOPに受け入れられたようです。私の解決策は彼の特定の問題に対する「十分な」解決策であり、リスト内の文字列が別の文字列にあるかどうかをチェックするための優れた一般的な方法ですが、これがこの解決策のすべてであることを覚えておいてください。たとえば、文字列の末尾など、文字列がどこにあるかは関係ありません。URLでよくあることですが、これが重要な場合は、@ Wladimir Palantの回答を確認する必要があります。そうしないと、誤検出が発生するおそれがあります。


1
これはまさに私が探していたものでした。私の場合、文字列のどこが拡張子であってもかまいません。ありがとう
pootzko

素晴らしい提案。この例を使用して、これは、引数のいずれかがよく知られているヘルプフラグと一致するかどうかを確認する方法です:any([x.lower()in ['-?'、 '-h'、 '-help'、 '/ h '] for x in sys.argv [1:]])
AX Labs

リスト内包表記を内部で使用する@ AXE-Labs anyは、すべての場合にリスト全体を作成する必要があるため、ショートサーキットがもたらす可能性のある利益の一部を無効にします。大括弧(any(x.lower() in ['-?','-h','--help', '/h'] for x in sys.argv[1:]))なしの式を使用する場合、x.lower() in [...]パーツはTrue値が見つかるまでのみ評価されます。
Lauritz V. Thaulow 2014年

5
そして、any()がTrueを返したときにextが何であるかを知りたいのですか?
Peter Senna

@PeterSennaは:any()のみを返しますまたはが、この変更して、以下のリスト内包答えを@psun参照してくださいprint [extension for extension in extensionsToCheck if(extension in url_string)]
Dannid

45
extensionsToCheck = ('.pdf', '.doc', '.xls')

'test.doc'.endswith(extensionsToCheck)   # returns True

'test.jpg'.endswith(extensionsToCheck)   # returns False

5
これは賢いです-タプルがそれを行うことができることを知りませんでした!しかし、それはあなたの部分文字列が文字列の一端に固定されている場合にのみ機能します。
Dannid

3
かっこいい。私は単に「で始まる」や「で終わる」ではなく、「含む」のようなものがあったらいいのに
BrDaHa

@BrDaHaは 'in'をcontainsに使用できます。リスト内の「文字列」の場合:
シェカールサマンタ

@ShekharSamanta確かに、しかしそれは複数のものの1つが文字列にあるかどうかをチェックする問題を解決しません、それは元の質問がそうだったということです。
BrDaHa

はい、その場合には、我々が使用することができます。もしあれば(のstring.Splitの要素(リスト内の要素のための「任意のdelmiter」))文字列の&もしあれば(リスト内の要素の文字列の要素)
シェカールSamanta

21

URLを適切に解析することをお勧めします。これによりhttp://.../file.doc?foohttp://.../foo.doc/file.exe正しく処理できます。

from urlparse import urlparse
import os
path = urlparse(url_string).path
ext = os.path.splitext(path)[1]
if ext in extensionsToCheck:
  print(url_string)

3

単一行のソリューションが必要な場合は、リスト内包表記を使用してください。次のコードは、拡張子が.doc、.pdf、.xlsの場合はurl_stringを含むリストを返し、拡張子が含まれていない場合は空のリストを返します。

print [url_string for extension in extensionsToCheck if(extension in url_string)]

注:これは、それが含まれているかどうかを確認するためだけのものであり、拡張子に一致する正確な単語を抽出する場合には役立ちません。


これはany解決策よりも読みやすく、私の意見ではその質問に対する最良の解決策の1つです。
Dmitry Verhoturov 16

これはany()、次のように特定の一致する値を返すように変更できるため、私の意見では解決策より優れていますprint [extension for extension in extensionsToCheck if(extension in url_string)](追加の詳細と一致する単語とurl_stringからのパターンを抽出する方法については、私の回答を参照してください)。
Dannid

2

この正規表現と一致するかどうかを確認します。

'(\.pdf$|\.doc$|\.xls$)'

注:拡張機能がURLの最後にない場合は、$文字を削除しますが、少し弱めます


1
これはURLですが、クエリ文字列がある場合はどうなりますか?
ウラジミールパラン

import re re.search(pattern、your_string)
juankysmith

この回答は指定されたケースで機能しますが、スケーラブルでも汎用的でもありません。一致させたいパターンごとに長い正規表現が必要です。
Dannid

1

これは、@ psunによって与えられたリスト内包回答のバリアントです。

出力値を切り替えることで、実際に一致パターンをリスト内包から抽出できます(any()@ Lauritz-v-Thaulowのアプローチでは不可能です)。

extensionsToCheck = ['.pdf', '.doc', '.xls']
url_string = 'http://.../foo.doc'

print [extension for extension in extensionsToCheck if(extension in url_string)]

['.doc'] `

さらに、一致したパターンが判明したら追加情報を収集したい場合は、正規表現を挿入できます(これは、許可されたパターンのリストが長すぎて単一の正規表現パターンに書き込めない場合に役立ちます)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)]

['foo.doc']

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