So überprüfen Sie, ob eine Zeichenfolge ein Element aus einer Liste in Python enthält

217

Ich habe so etwas:

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

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

Ich frage mich, wie dies in Python eleganter wäre (ohne die for-Schleife zu verwenden). Ich habe an so etwas gedacht (wie aus C / C ++), aber es hat nicht funktioniert:

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

Bearbeiten: Ich bin gezwungen zu erklären, wie sich dies von der Frage unterscheidet, die als potenzielles Duplikat markiert ist (damit es wohl nicht geschlossen wird).

Der Unterschied besteht darin, dass ich überprüfen wollte, ob eine Zeichenfolge Teil einer Liste von Zeichenfolgen ist, während die andere Frage darin besteht, zu überprüfen, ob eine Zeichenfolge aus einer Liste von Zeichenfolgen eine Teilzeichenfolge einer anderen Zeichenfolge ist. Ähnlich, aber nicht ganz gleich und Semantik ist wichtig, wenn Sie meiner Meinung nach online nach einer Antwort suchen. Diese beiden Fragen versuchen tatsächlich, das entgegengesetzte Problem voneinander zu lösen. Die Lösung für beide ist jedoch dieselbe.

pootzko
quelle

Antworten:

418

Verwenden Sie zusammen mit einem Generator any, der beim ersten True kurzschließt:

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

EDIT: Ich sehe, dass diese Antwort von OP akzeptiert wurde. Obwohl meine Lösung "gut genug" für sein spezielles Problem sein kann und eine gute allgemeine Methode ist, um zu überprüfen, ob Zeichenfolgen in einer Liste in einer anderen Zeichenfolge gefunden werden, denken Sie daran, dass dies alles ist, was diese Lösung tut. Es ist egal, wo sich die Zeichenfolge befindet, z. B. am Ende der Zeichenfolge . Wenn dies wichtig ist, wie dies häufig bei URLs der Fall ist, sollten Sie auf die Antwort von @Wladimir Palant achten, da sonst die Gefahr besteht, dass Sie falsch positive Ergebnisse erhalten.

Lauritz V. Thaulow
quelle
1
das war genau das, wonach ich gesucht habe. In meinem Fall spielt es keine Rolle, wo in der Zeichenfolge die Erweiterung ist. danke
pootzko
Toller Vorschlag. Anhand dieses Beispiels überprüfe ich, ob eines der Argumente den bekannten Hilfe-Flags entspricht: any ([x.lower () in ['-?', '- h', '- help', '/ h '] für x in sys.argv [1:]])
AX Labs
@ AX-Labs, die Listenverständnisse verwenden any, negieren einige der möglichen Vorteile, die ein Kurzschluss bietet, da in jedem Fall die gesamte Liste erstellt werden muss. Wenn Sie den Ausdruck ohne eckige Klammern ( any(x.lower() in ['-?','-h','--help', '/h'] for x in sys.argv[1:])) verwenden, wird das x.lower() in [...]Teil nur ausgewertet, bis ein True-Wert gefunden wurde.
Lauritz V. Thaulow
5
Und wenn ich wissen will, was ext ist, wenn any () True zurückgibt?
Peter Senna
@PeterSenna: any()gibt nur wahr oder falsch zurück , aber siehe @psuns Liste Verständnis Antwort unten mit dieser Änderung: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
Eumiro
quelle
5
Dieser ist clever - ich wusste nicht, dass Tupel das können!, aber er funktioniert nur, wenn Ihr Teilstring an einem Ende des Strings verankert ist.
Dannid
3
Viel cooler. Ich wünschte nur, es gäbe so etwas wie "enthält" und nicht nur Start oder Ende
BrDaHa
@BrDaHa können Sie 'in' für enthält verwenden. wenn 'string' in der Liste:
Shekhar Samanta
@ ShekharSamanta sicher, aber das löst nicht das Problem, zu überprüfen, ob eines von mehreren Dingen in einer Zeichenfolge enthalten ist, worum es bei der ursprünglichen Frage ging.
BrDaHa
Ja, in diesem Fall können wir verwenden: falls vorhanden (Element in string.split ('beliebiger Delmiter') für Element in Liste) und für Zeichenfolge, falls vorhanden (Element in Zeichenfolge für Element in Liste)
Shekhar Samanta
21

Es ist besser , die URL richtig zu analysieren - auf diese Weise Sie behandeln können http://.../file.doc?foound http://.../foo.doc/file.exerichtig.

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

Verwenden Sie Listenverständnisse, wenn Sie eine einzeilige Lösung wünschen. Der folgende Code gibt eine Liste mit der URL-Zeichenfolge zurück, wenn sie die Erweiterungen .doc, .pdf und .xls enthält, oder gibt eine leere Liste zurück, wenn sie die Erweiterung nicht enthält.

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

HINWEIS: Dies dient nur zur Überprüfung, ob es enthält oder nicht, und ist nicht nützlich, wenn das genaue Wort extrahiert werden soll, das den Erweiterungen entspricht.

psun
quelle
Dies ist besser lesbar als eine anyLösung. Meiner Meinung nach ist es eine der bestmöglichen Lösungen für diese Frage.
Dmitry Verhoturov
Dieser ist any()meiner Meinung nach der Lösung überlegen, da er geändert werden kann, um auch den spezifischen Übereinstimmungswert zurückzugeben, wie folgt : print [extension for extension in extensionsToCheck if(extension in url_string)](Weitere Informationen und das Extrahieren des übereinstimmenden Wortes sowie des Musters aus der URL-Zeichenfolge finden Sie in meiner Antwort. )
Dannid
2

Überprüfen Sie, ob es zu diesem regulären Ausdruck passt:

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

Hinweis: Wenn sich Ihre Erweiterungen nicht am Ende der URL befinden, entfernen Sie die $Zeichen, sie werden jedoch leicht geschwächt


quelle
1
Es ist eine URL. Was ist, wenn sie eine Abfragezeichenfolge enthält?
Wladimir Palant
Import re re.search (Muster, your_string)
Juankysmith
Diese Antwort funktioniert zwar für den angegebenen Fall, ist jedoch nicht skalierbar oder generisch. Sie benötigen eine lange Regex für jedes Muster, das Sie abgleichen möchten.
Dannid
1

Dies ist eine Variante der Listenverständnisantwort von @psun.

Durch Umschalten des Ausgabewerts können Sie das Übereinstimmungsmuster tatsächlich aus dem Listenverständnis extrahieren (was mit dem any()Ansatz von @ Lauritz-v-Thaulow nicht möglich ist ).

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

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

['.doc'] `

Sie können außerdem einen regulären Ausdruck einfügen, wenn Sie zusätzliche Informationen sammeln möchten, sobald das übereinstimmende Muster bekannt ist (dies kann nützlich sein, wenn die Liste der zulässigen Muster zu lang ist, um in ein einzelnes Regex-Muster zu schreiben).

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

['foo.doc']

Dannid
quelle