Überprüfen Sie, ob in einer anderen Zeichenfolge mehrere Zeichenfolgen vorhanden sind


378

Wie kann ich überprüfen, ob eine der Zeichenfolgen in einem Array in einer anderen Zeichenfolge vorhanden ist?

Mögen:

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"

Dieser Code funktioniert nicht, er soll nur zeigen, was ich erreichen möchte.


5
Ich bin überrascht, dass es (noch) keine Antworten im Vergleich zu einem kompilierten regulären Ausdruck in Bezug auf Perf gibt, insbesondere im Vergleich zur Größe der Zeichenfolge und der Anzahl der zu suchenden "Nadeln".
Pat

3
@Pat Ich bin nicht überrascht. Die Frage betrifft nicht die Leistung. Heutzutage legen die meisten Programmierer mehr Wert auf die Erledigung und Lesbarkeit. Die Leistungsfrage ist gültig, aber eine andere Frage.
Guettli

13
Die Verwendung von str als Variable ist verwirrend und kann zu unerwartetem Verhalten führen, da es sich um ein reserviertes Wort handelt. siehe Link .
Clever Guy

Regex [abc]funktioniert auch perfekt und ist schneller, wenn mehr als ein paar Kandidaten getestet werden müssen. Wenn die Zeichenfolgen jedoch beliebig sind und Sie sie nicht im Voraus kennen, um einen regulären Ausdruck zu erstellen, müssen Sie den any(x in str for x in a)Ansatz verwenden.
smci

@CleverGuy Sie haben Recht, obwohl es kein reserviertes Wort ist, sonst könnten Sie es nicht zuweisen. Es ist ein eingebautes.
Wjandrea

Antworten:


717

Sie können verwenden any:

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

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

Verwenden Sie anstelle von , um zu überprüfen, ob alle Zeichenfolgen aus der Liste gefunden wurden .allany


11
any () nimmt eine iterable. Ich bin nicht sicher, welche Version von Python Sie verwenden, aber in 2.6 müssen Sie [] um Ihr Argument zu any () setzen. any ([x in str für x in a]), so dass das Verständnis eine iterable zurückgibt. Aber vielleicht tun dies spätere Versionen von Python bereits.
Emispowder

7
@ Mark Byers: Entschuldigen Sie den späten Kommentar, aber gibt es eine Möglichkeit, die gefundene Zeichenfolge zu drucken? Wie würden Sie das tun? Vielen Dank.
Shankar Kumar

3
Ich bin mir nicht sicher, ob ich verstehe, ob a die Liste ist und str die Sache ist, mit der man übereinstimmen kann. Was ist das x? Python-Neuling ftw. :)
rot

2
@red: Sie können for x in awie "für jedes Element in der Liste" lesen . Da aes sich um eine Liste von Zeichenfolgen handelt und xein Element dieser Liste ist, xhandelt es sich um eine Zeichenfolge (im ursprünglichen Beispiel eine von 'a', 'b', 'c')
Benutzer

6
@emispowder Es funktioniert gut für mich wie es ist in Python 2.6.9.
MPlanchard

67

any()ist bei weitem der beste Ansatz, wenn alles , was Sie wollen, Trueoder ist False, aber wenn Sie genau wissen möchten, welche Zeichenfolge / Zeichenfolgen übereinstimmen, können Sie ein paar Dinge verwenden.

Wenn Sie die erste Übereinstimmung wünschen ( Falsestandardmäßig mit):

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

Wenn Sie alle Übereinstimmungen (einschließlich Duplikate) erhalten möchten:

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

Wenn Sie alle nicht doppelten Übereinstimmungen erhalten möchten (ohne Berücksichtigung der Reihenfolge):

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

Wenn Sie alle nicht doppelten Übereinstimmungen in der richtigen Reihenfolge erhalten möchten:

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

Bitte fügen Sie auch ein Beispiel für das letzte Spiel hinzu
Oleg Kokorin

@OlegKokorin: Es wird eine Liste übereinstimmender Zeichenfolgen in derselben Reihenfolge erstellt, in der sie gefunden werden. Es wird jedoch nur die erste beibehalten, wenn zwei gleich sind.
Zondo

Die Verwendung von OrderedDictist wahrscheinlich leistungsfähiger als eine Liste. Siehe diese Antwort unter "Entfernen von Duplikaten in Listen"
wjandrea

44

Sie sollten vorsichtig sein , wenn die Strings in aoder strlänger werden. Die einfachen Lösungen nehmen O (S * (A ^ 2)), wobei Sdie Länge von strund A die Summe der Längen aller Strings in ist a. Eine schnellere Lösung finden Sie im Aho-Corasick- Algorithmus für die Zeichenfolgenanpassung, die in der linearen Zeit O (S + A) ausgeführt wird.


Kann Aho-Corasick auch Teilzeichenfolgen anstelle von Präfixen finden?
RetroCode

1
Einige Python Aho-Corasick Bibliotheken sind hier und hier
vorpal

23

Nur um etwas Abwechslung zu schaffen mit regex:

import re

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

oder wenn Ihre Liste zu lang ist - any(re.findall(r'|'.join(a), str, re.IGNORECASE))


1
Dies funktioniert für den gegebenen Anwendungsfall der Frage. Wenn die Suchen Sie (oder *dies nicht gelingt, da unter Angabe für die regex Syntax getan werden muss.
Guettli

2
Sie können es bei Bedarf mit entkommen '|'.join(map(re.escape, strings_to_match)). Sie sollten wahrscheinlich re.compile('|'.join(...))auch.
Artyer

12

Sie müssen die Elemente von a iterieren.

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
Ja, ich wusste, wie man das macht, aber im Vergleich zu Marks Antwort ist das schrecklicher Code.
Jahmax

10
Nur wenn Sie Marks Code verstehen. Das Problem, das Sie hatten, ist, dass Sie die Elemente Ihres Arrays nicht untersucht haben. Es gibt viele knappe, pythonische Wege, um das zu erreichen, was Sie wollen, um die Essenz dessen zu verbergen, was mit Ihrem Code nicht stimmte.
Seamus Campbell

9
Es mag 'schrecklicher Code' sein, aber es ist genau das, was any () tut . Außerdem erhalten Sie die tatsächliche Zeichenfolge, die übereinstimmt, während any () nur angibt, dass eine Übereinstimmung vorliegt.
Alldayremix

4

jbernadas erwähnte bereits den Aho-Corasick-Algorithmus , um die Komplexität zu reduzieren.

Hier ist eine Möglichkeit, es in Python zu verwenden:

  1. Laden Sie hier aho_corasick.py herunter

  2. Legen Sie es in dasselbe Verzeichnis wie Ihre Python-Hauptdatei und benennen Sie es aho_corasick.py

  3. Versuchen Sie den Alrorithmus mit dem folgenden Code:

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

Beachten Sie, dass bei der Suche zwischen Groß- und Kleinschreibung unterschieden wird


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

Es hängt vom Kontext nehme an, wenn Sie einzelne wörtliche überprüfen , wie wollen (ein beliebiges Wort, e, w, .. etc) in genügt

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

Wenn Sie eines der Zeichen im Originalwort überprüfen möchten, verwenden Sie

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

Wenn Sie alle Eingaben in diesem Originalwort wünschen, verwenden Sie alle einfachen

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

Was wäre Ihr Beitrag? Ich kann zwei Dinge erkennen: den Satz, in dem ich nach etwas suche. Die Reihe von Wörtern, die ich suche. Aber Sie beschreiben drei Variablen und ich kann nicht verstehen, was die dritte ist.
Mayid

1

Nur ein paar Infos, wie man alle Listenelemente in String verfügbar macht

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

1

Ein überraschend schneller Ansatz ist 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")

Dies funktioniert, wenn akeine Werte mit mehreren Zeichen enthalten sind (in diesem Fall anywie oben aufgeführt ). Wenn ja, ist es einfacher, aals Zeichenfolge anzugeben : 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')

Beispielbild ausgeben


0

Ich würde diese Art von Funktion für die Geschwindigkeit verwenden:

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)));
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.