Elemente aus Dict / Liste unabhängig vom Wert entfernen

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
Spedex
User
Beiträge: 54
Registriert: Mittwoch 29. Januar 2020, 03:27

Hallo, schaut euch bitte mal folgendes beispielhaftes Dictionary an:

Code: Alles auswählen

dict_test = {"eintrag1":"9 q", "eintrag2":"12 d", "eintrag3":"Etwas anderes"}
Ich möchte nun die Einträge, bei welchen sich als Wert hinten ein Buchstabe befindet, wie beispielsweise q oder d, in eine neue Liste packen und zwar als Float-Variable. Allerdings nur die Zahl davon, nicht der Buchstabe wie q oder d. Es gibt auch Einträge, die nicht eine Zahl mit einem Buchstaben als Wert haben. Diese sollen ignoriert werden, wurden schon davor in eine andere Liste gepackt.
Wichtig dabei ist: ob und welcher Buchstabe bei einem Wert im Dict steht, wissen wir nicht. Sprich wir können das nicht hard-coden.
Ebenfalls zu beachten: Meine Problemstellung habe ich auf dieses Beispiel übertragen. Wie schon erwähnt, gibt es auch noch andere Einträge. Diese werden mit der if-Bedingung im if-Statement abgefangen.
Die Einträge, die uns interessieren, sollen im else-Statement bearbeitet werden.

Ich habe dabei nur Lösungen gefunden, welche allerdings hard-gecodet sind:
Das schaut dann beispielsweise so aus:

Code: Alles auswählen

dict_test = {"eintrag1":"9 q", "eintrag2":"12 d", "eintrag3":"Etwas anderes"}

neue_Liste = []

for key in dict_test:
    if "Etwas anderes" in dict_test[key]:
        ...
    else:
        try:
            neue_Liste.append(float(neue_Liste[key].strip("q")))
        except:
            pass
        try:
            neue_Liste.append(float(neue_Liste[key].strip("d")))
        except:
            pass
Ich hoffe ich habe das einigermaßen verständlich erklärt.

Könnt ihr mir hier weiterhelfen, wie ich das ganze so automatisieren kann, dass ich nicht wissen muss, welcher Buchstabe gerade "daher kommt"?

Liebe Grüße
Spedex
Benutzeravatar
__blackjack__
User
Beiträge: 13114
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Spedex: Erst mal verwendest Du `strip()` falsch. Selbst wenn das bei den vorhandenen Daten nie ein Problem ist (ist es das wirklich nicht?) oder werden könnte (sind wir uns da wirklich sicher?) sagt die Verwendung dieser Methode etwas anderes als Du an der Stelle machen willst.

Wobei der erste Punkt eigentlich sein sollte: Niemals nackte ``except:``\s ohne konkrete Ausnahmen. Und dann auch noch ignorieren! Reagiere da auf genau die Ausnahme die Du erwartest und ignorieren willst, nicht einfach *alle*.

Warum kodierst Du nicht das was Du sagst: das muss mit einem Buchstaben enden, dann teste doch einfach ob es das tut. Falls das Muster „Zahl, Leerzeichen, Buchstabe“ ist, dann trenn von hinten am Leerzeichen, teste ob das nach dem Leerzeichen ein Buchstabe ist und sich das vor dem Trennzeichen in eine Gleitkommazahl umwandeln lässt.

Alternativ könnte man das Muster auch mit einem regulären Ausdruck beschreiben und damit testen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Spedex
User
Beiträge: 54
Registriert: Mittwoch 29. Januar 2020, 03:27

Hallo, danke für deine Antwort. Die Methode strip() hat bis jetzt keine Probleme verursacht und funktioniert so tatsächlich auch einwandfrei bei meinem Beispiel, auch wenn ich es falsch verwende.
Das mit dem try und except sollte ich eigentlich eh nicht brauchen, wenn ich es richtig machen würde.
Bezüglich dem Abfragen, ob dahinter ein Buchstabe kommt:
Ich hab das Problem ja nur auf dieses Beispiel übertragen, leider stehen beim tatsächlichen Beispiel keine Buchstaben, sondern Mengeneinheiten wie beispielsweise "Stueck" oder "Kisten" oder "Becher", jeweils mit unterschiedliche Menge.

Aber vom Prinzip her kann man es trotzdem machen, indem man es auch einfach beim Leerzeichen trennt.

Code: Alles auswählen

dict_test = {"eintrag1":"9 q", "eintrag2":"12 d", "eintrag3":"Etwas anderes"}

neue_Liste = []
extrahiert = None
for key in dict_test:
    if "Etwas anderes" in dict_test[key]:
        pass
    else:
        extrahiert = dict_test[key].split(" ")
        neue_Liste.append(float(extrahiert[0]))
    
print(neue_Liste)
Das hat funktioniert.

LG
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum initalisierst Du extrahiert mit None? Das wird doch gar nicht gebraucht.
Spedex
User
Beiträge: 54
Registriert: Mittwoch 29. Januar 2020, 03:27

Bin ich dann auch draufgekommen. Ist schon weg. Danke.
Benutzeravatar
__blackjack__
User
Beiträge: 13114
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Spedex: Du scheinst ja nur die Werte zu verwenden, warum iterierst Du dann über die Schlüssel und nicht über wie Werte? Und falls beides benötigt wird, würde man gleich über beides iterieren.

Das `split()` könnte man noch in der Anzahl beschränken.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
DeaD_EyE
User
Beiträge: 1021
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Die strip-Methode hat so ziemlich jeder falsch verstanden:

Code: Alles auswählen

>>> "abraWetterrba".strip("abra")
'Wette'
Oh, das r ist abhandengekommen.
Die Annahme Python würde exakt den kompletten String links und rechts vom originalen String entfernen (Kopie), ist falsch.
  • lstrip entfernt von links aus einem String alle Zeichen, die in der Sequenz chars vorkommen und stoppt, sobald ein Zeichen im String vorkommt, dass nicht in chars enthalten ist.
  • rstrip entfernt von rechts aus einem String alle Zeichen. Wie bei lstrip, entfernt rstrip keine Zeichen mehr, wenn das erste Zeichen von rechts nicht in chars vorkommt.
  • strip macht es von beiden Seiten mit den gleichen Bedingungen wie lstrip und rstrip.
Aufgrund der Verständnisprobleme hat man dann für Abhilfe geschaffen: https://docs.python.org/3/whatsnew/3.9. ... d-suffixes
Noch ein Grund Python 3.9 zu verwenden.

Für ältere Python-Versionen gibt es unterschiedliche Lösungen um ein Präfix oder Suffix zu entfernen.

Code: Alles auswählen

def removeprefix(text, match):
    if not text.startswith(match):
        return text
    else:
        return text[len(match):]


def removesuffix(text, match):
    if not text.endswith(match):
        return text
    else:
        return text[:-len(match)]
Wichtig ist hierbei, dass das Suffix oder Präfix exakt passen muss. Wenn z.B. am Anfang des Strings ein Leerzeichen ist, wird der Präfix/Suffix z.B. nicht entfernt, selbst wenn der folgende Text den gesuchten String enthalten ist.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten