Listenelemente in String finden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Hart mit Bart
User
Beiträge: 25
Registriert: Dienstag 30. Oktober 2018, 12:05

Servus zusammen.

Ich fuchse mich gerade ein wenig in Python ein und hänge peinlicherweise an einer Stelle fest.

Code: Alles auswählen

mein_string = "Das ist mein String"
meine_liste = ["a", "b", "c", "d"]
Jetzt möchte ich möglichst kurz und sauber prüfen, ob ein Beliebiges der Listenelemente in meinem String vorkommt.

Mit ...

Code: Alles auswählen

if meine_liste in mein_string:
    ...
else
    ...
... befinde ich mich ganz offensichtlich auf dem Holzweg. Sicherlich ist die Antwort eine ganz Simple, aber ich bekomme es gerade nicht heraus. Ich werde ja wohl nicht einzeln durch alle Listenelemente loopen müssen, oder?

Liebe Grüße
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Doch, genau das musst du tun. Ueber jedes Element loopen. Das kann man mit dem builtin "any" aesthetisch etwas ansprechender gestalten, aber konzeptionell geht's halt nicht anders.
Hart mit Bart
User
Beiträge: 25
Registriert: Dienstag 30. Oktober 2018, 12:05

Hmm. Danke dir.

Ich habe das jetzt so gelöst:

Code: Alles auswählen

def is_list_element_in_string(list, string):
    for string_element in string:
        for list_element in list:
            if list_element == string_element:
                return True
    return False
Das tut was es soll.

"Any" schaue ich mir später mal an.
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Hart mit Bart: Die äussere Schleife kann man sich sparen wenn man den ``in``-Operator für den Test benutzt ob eine Zeichenkette in einer anderen Zeichenkette enthalten ist.

Die Funktion ist zudem generischer als die verwendeten Namen vermuten lassen, denn `list` und `string` können beliebiege Sequenztypen sein, eines davon, je nachdem wie man die Schleifen anordnet braucht sogar nur ein iterierbares Objekt sein.

`list` ist keine gute Namenswahl, weil es bereits den eingebauten Datentyp mit dem gleichen Namen gibt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ein möglicher Einzeiler wäre noch die Verwendung von Sets:

Code: Alles auswählen

if set(text) & set('abc'):
    # Text enthält mind. einen der Buchstaben
    ...
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Hart mit Bart: das funktioniert jetzt nur, wenn die einzelne Buchstaben suchst, die Funktion sollte daher besser `is_one_of_characters_in_string` heißen.
Hart mit Bart
User
Beiträge: 25
Registriert: Dienstag 30. Oktober 2018, 12:05

@_blackjack_
Ah, ja. Solche Details bringen einen später zu Fall, wenn das Script langsam aufzuufern beginnt. Du hast recht, das war nicht sehr spezifisch.
Wieso kann ich mir die äußere Schleife sparen? Ich dachte, ich müsse jedes Element der Liste mit jedem Buchstaben des Strings vergleichen. *am Kopf kratz*

@Sirius
Das ist der Sinn. Die Liste enthält definitiv und ausschließlich nur einzelne Buchstaben. Der String ist ein Ausdruck, welcher neben Buchstaben nur Leerzeichen oder Bindestriche enthält.

@snafu
Umpf ... dann bräuchte ich die Buchstaben gar nicht in einer Liste zu speichern, sondern könnte diese auch als String speichern. *grübel*

Also, es geht um folgendes:
Ich möchte als Übung ein kleines Spiel programmieren. Meine Wahl fiel auf das Spiel Galgenmännchen.

- Zuerst wähle ich aus einer Textdatei einen zufälligen Begriff aus. Kein Problem.
- Dann lasse ich für jeden Buchstaben des Wortes, der kein "-" oder " " ist ein "_" ausgeben. Da hakelt noch etwas. Es wird ein "_" zu viel ausgegeben.
- Jetzt muss man einen Buchstaben eingeben. (Fehleingaben muss ich später noch abfangen) Alle bereits probierten Buchstaben speichere ich in besagter Liste.
- Jetzt muss die Anzeige mit eventuell gefundenen Buchstaben neu angezeigt werden
- Das Ganze geht weiter, bis man entweder das Wort erraten oder x Fehlversuche hat

Gar nicht so schwer eigentlich, aber doch mit einigen Fallstricken. Zum Beispiel, wie prüfe ich am besten, ob alle Buchstaben erraten wurden? Es sind die Details, an denen ich rumknabbere.

Ich kommentiere auch brav alle wichtigen Stellen, damit ich morgen noch weiß, was zum Geier ich mir eigentlich dabei gedacht habe.

Mal sehen, ich fuchse mich da schon rein. Das ist ja alles noch Grundlagenwissen, möchte ich meinen. Wenn ich eine erste lauffähige Version habe, lasse ich euch da mal drüber schauen. Nicht, dass ich mir Unsauberkeiten angewöhne.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Für solche Fragen sind ja Mengenoperationen (Sets) da: bei der Anzeige, ist der Buchstabe in der Menge der geratenen Buchstaben? Für das Ende, ist die Menge der Buchstaben des Wortes komplett in der Menge der geratenen Buchstaben enthalten, ...
Ergo, keine Liste sondern ein Set benutzen.
Hart mit Bart
User
Beiträge: 25
Registriert: Dienstag 30. Oktober 2018, 12:05

Die erste Version meines Spiels ist nun lauffähig und tut grundsätzlich, was es soll. Nur die Sache mit den Umlauten haut nicht hin. Ursprünglich wollte ich alle Umlaute in ihre zweibuchstabige Schreibweise umwandeln, fand dann aber, dass das nicht sehr zeitgemäß ist. Und irgendwann stehe ich eh wieder vor dem gleichen Problem, richtig? Genau, also lieber gleich lernen.
Mein Script liest aus einer Datei eine zufällige Zeile aus. Diese kann Umlaute enthalten. Und genau an dem Punkt funktioniert das Spiel nicht mehr. Script und Textdatei habe ich im gleichen Editor erstellt, bearbeitet und gespeichert: PyCharm Community Edition Version 2018.2.4 für Windows. Eigentlich sollten die Encodings doch die gleichen sein.

Kann mir bitte jemand einen Stoß in die richtige Richtung geben?
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Hart mit Bart: „Funktioniert nicht“ ist keine Fehlerbeschreibung bei man etwas anderes sagen kann als „dann machst Du wohl irgend etwas falsch“.

Zeig den Code und beschreibe was nicht funktioniert. Was erwartest Du, und was passiert stattdessen. Falls Ausnahme, den Stacktrace 1:1 zeigen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Hart mit Bart
User
Beiträge: 25
Registriert: Dienstag 30. Oktober 2018, 12:05

Kein Problem. Morgen beginne ich mit glaskugel.py :mrgreen:

Du hast recht. "Funktioniert nicht" ist jetzt eher so semi- bis gar nicht hilfreich. :roll: Das Script habe ich absichtlich noch nicht mitgeliefert, weil ich noch nach bestem WIssen und Gewissen ein wenig aufräumen und auskommentieren möchte, um mir zumindest eine Totalblamage zu ersparen. :shock:

Das Problem war (darauf komme ich gleich) folgendes:
Es wird ein zufälliges Wort aus einer Datei gewählt und entsprechend der bisher erratenen Buchstaben auf dem Bildschirm ausgegeben. Nicht erratene Buchstaben erscheinen, wie gewohnt, als "_". Bei dem Wort "Bär" wäre die korrekte Ausgabe also "_ _ _". Tatsächlich ausgegeben wurde aber "_ _ _ _". Der Umlaut war nicht erratbar.

Gelöst habe ich das so:

Code: Alles auswählen

import codecs

word_to_guess = random.choice(codecs.open("testdatei.txt", "r", "utf-8").readlines()).strip("\n")
Jetzt funktioniert alles so, wie ich das haben möchte.

Da ich an dem kleinen Projekt noch weiter rumbasteln und es erweitern möchte (ich lerne nicht gezielt, sondern eher abhängig von dem, was sich als Notwendigkeit ergibt), mache ich vielleicht einen eigenen Faden auf. Das sprengt das Thema hier doch langsam.
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Hart mit Bart: Ich würde eher `io.open()` verwenden, das ist näher an der `open()`-Funktion von Python 3 dran.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Hart mit Bart
User
Beiträge: 25
Registriert: Dienstag 30. Oktober 2018, 12:05

Ich habe mein Projekt jetzt mal hier vorgestellt. Alle weiteren Fragen, die sich in Verbindung damit ergeben mögen, werde ich dann dort stellen.
Antworten