dictionary key ausgeben

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
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

Hi Leute,

es geht um diesen Code hier:

Code: Alles auswählen

fobj = open('bsp.txt', 'r')

wo_dict = {}
for line in fobj:
    line = line.strip()
    zuordnung = line.split(' ')
    wo_dict[zuordnung[0]] = zuordnung[1]

nutzerfrage = input()

if nutzerfrage in wo_dict:
    print(wo_dict[nutzerfrage])
else:
    for key, value in wo_dict.items():
        print(wo_dict[key])
und zwar habe ich eine Textdatei mit:

Deutschland Germany
Fankreich France
Spanien Spain


erstellt. Nun will ich das Programm so erweitern, dass, falls die nutzerfrage den value des dictionarys entspricht, dass dann demnach der key ausgegeben werden soll (der deutsche Begriff) Hat jemand dazu eine Idee?

Danke fürs Antworten:D
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@norgsmen: Was willst Du denn da erweitern? Das was Du beschreibst, leistet das Programm doch schon‽

Anmerkungen zum Quelltext: Namen sollten keine kryptischen Abkürzungen enthalten. Der Zweck von Namen ist es dem Leser klar zu vermitteln wofür der Wert dahinter im Programm steht. Namen wie `fobj` und `wo_dict` tun das nicht. Beim `fobj` macht das `obj` nicht wirklich Sinn, denn *alles* was man an einen Namen binden kann, ist in Python ein Objekt.

Grunddatentypen wie `dict` haben in Namen auch nichts zu suchen. Während der Entwicklung kann es vorkommen, dass man einen Datentyp durch einen anderen, spezialisierteren ersetzt, und dann hat man entweder falsche, irreführende Namen im Quelltext, oder muss alle betroffenen Namen suchen und anpassen.

`key` und `value` sind zwar Namen die nicht abgekürzt sind und auch keine Grunddatentypen enthalten, aber sie sind sehr allgemein gehalten. Da sollte man bessere Namen verwenden, welche die Bedeutung der Werte enthalten. Wie `german_country_name` und `english_country_name`.

Wörterbüchern werden oft Namen nach dem Muster `key_to_value` benannt, wobei für `key` etwas gewählt wird das einen einzelnen Schlüssel beschreibt, und für `value` etwas das einen einzelnen Wert beschreibt.

Man sollte nicht verschiedene Sprachen für Namen verwenden, denn sonst muss man immer überlegen ob man einen Deutschen oder einen Englischen Bezeichner verwendet hat.

Man muss auch nicht jedes Zwischenergebnis an einen Namen binden.

Beim öffnen von Textdateien sollte man immer explizit die Kodierung angeben. Denn bei Ländern mit Zeichen ausserhalb von ASCII-Zeichen, z.B. Österreich muss man dem Programm mitteilen, wie die kodiert sind, und sich nicht auf die Kodierung verlassen, die Python ”rät”, und die auf unterschiedlichen Systemen anders sein kann.

Dateien die man öffnet, sollte man auch wieder schliessen. Am besten verwendet man wo es geht die ``with``-Anweisung dafür.

Statt undurchsichtiger Indexzugriffe sollte man die beiden Teile der am Leerzeichen getrennten Zeile gleich an sinnvolle Namen binden.

Wobei das mit den Leerzeichen ein Problem ist, denn es gibt sowohl im Deutschen als auch im Englischen Ländernamen mit Leerzeichen. Siehe Kommetar im Quelltext weiter unten.

Die ``for``-Schleife bei der Ausgabe verwendet `value` gar nicht, dafür `key` nur im den `value` dazu zu ermitteln, den man durch die ``for``-Schleife ja bereits hätte, womit `key` das ist, was eigentlich gar nicht benötigt wird. Man könnte da einfach direkt nur über die Werte iterieren.

Hier der überarbeitete Quelltext (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3


def main():
    with open("bsp.txt", encoding="ascii") as lines:
        german_to_english_country_name = {}
        for line in lines:
            #
            # BUG This doesn't work with country names, german or english,
            # containing spaces.  For instance Costa Rica, Burkina Faso, Puerto
            # Rico and so on.
            #
            german_name, english_name = line.strip().split(" ")
            german_to_english_country_name[german_name] = english_name

    german_name = input()
    if german_name in german_to_english_country_name:
        print(german_to_english_country_name[german_name])
    else:
        for english_name in german_to_english_country_name.values():
            print(english_name)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

@__blackjack__ Hi, danke für die ganzen Tipps. Also wenn ich als nutzerfrage 'Deutschland' eingeben, dann wird so wie ich es erwarte 'Germany' ausgegeben.
Aber ich will, dass das auch anderes herum funktioniert. Und zwar, wenn ich 'Germany' angebe, dann soll nur 'Deutschland' ausgegeben werden. Bei mir kommt das hier:

Germany
Germany
France
Spain
Benutzeravatar
snafu
User
Beiträge: 6871
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Dann kehre das Wörterbuch halt um:

Code: Alles auswählen

english_to_german = {english: german for german, english in german_to_english.item()}
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

@snafu Es hat geklappt! Dankeschön:)
Benutzeravatar
DeaD_EyE
User
Beiträge: 1240
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Hier mal ein ähnlicher Ansatz mit mehr Code:

Code: Alles auswählen

END = "\n" * 2


def load_data(textfile):
    with open(textfile) as fd:
        ger2eng = {row[0]: row[1] for line in fd if (row := line.strip().split())}

    eng2ger = {value: key for key, value in ger2eng.items()}
    return ger2eng, eng2ger


def nutzerfrage(ger, eng):
    """
    - Leerzeichen werden links und rechts vom string abgeschnitten
    - Anfangsbuchstaben der Wörter groß schreiben (title())
    - dann die Englische oder Deutsche übersetzung zurückliefern
    - wenn beide nicht zutreffen, liefert die get-methode ein None zurück
    """
    user_input = input().strip().title()
    return ger.get(user_input) or eng.get(user_input), user_input


def main():
    """
    Hauptfunktion mit Endlossschleife
    """
    ger_mapping, eng_mapping = load_data("bsp.txt")
    print("STRG+C zum beenden", end=END * 2)

    while True:
        antwort, benutzer_eingabe = nutzerfrage(ger_mapping, eng_mapping)
        if antwort is None:
            print(f"Wort {benutzer_eingabe} nicht gefunden", end=END)
        else:
            print(f"Übersetzung: {antwort}", end=END)


if __name__ == "__main__":
    # wird nur ausgeführt, wenn das Programm mit Python gestartet wird
    # wird nicht ausgeführt, wenn dieses Modul durch Python importiert wird
    # KeyboardInterrupt abfangen, um das Programm mit STRG+C beenden zu können
    # und um einen Text auszugeben. \r springt zum Anfang der Zeile zurück.
    # Wenn man STRG+C betätigt, erscheint in der Konsole die Zeichenfolge ^C.
    try:
        main()
    except KeyboardInterrupt:
        print("\rProgramm beendet.")
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten