Dict: key mit 2 Werten

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
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

Hallo,
ich versuche in einem Dict für ein kleines "Rate-Spiel" einem FilmZitat einen Film zuzuordnen. Sieht dann folgendermaßen aus:

Code: Alles auswählen

def main():

    HDR1 = "Du kannst nicht vorbei!"
    SW1 = "Ich bin dein Vater!"
    B1 = "Mein Name ist Bond."

    Liste = [HDR1, SW1, B1]

    fz = {
        
        HDR1: "Herr der Ringe",
        SW1: "Star Wars",
        B1: "James Bond"

    }

    zufall = random.choice(Liste)

    print("Ihr Zitat: %s" % zufall)

    eingabe = str(input("Film: "))

    if fz[zufall] == eingabe:
        print("Richtig!")
Funktioniert einwandfrei. Aber jetzt gibt es das Problem, dass man ja dem ersten Zitat sowohl "Herr der Ringe" als auch "DER Herr der Ringe" zuordnen könnte. Ich habe versucht, einfach das ganze nochmal ins dict zu hängen:

Code: Alles auswählen

 fz = {
        
        HDR1: "Herr der Ringe",
        HDR1: "Der Herr der Ringe",
        SW1: "Star Wars",
        B1: "James Bond"

    }
Dabei wird aber der erste Wert einfach überschrieben... Gibts ne möglichst kompakte & simple Möglichkeit, dem Key HDR1 einen zweiten Wert zuzuweißen, ohne den ersten zu überschreiben?
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das wäre möglich, wenn du einfach Listen anstatt Einzelwerte benutzt. Oder indem du die Schlüssel-Wert-Beziehung umdrehst (was mir sowieso sinnvoller erscheint). Dann gibt es verschiedene Variationen als Schlüssel und der Wert ist immer das Kürzel. Für die korrekte Antwort schaut man dann einfach, welches Kürzel vorliegt.
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

aber ewnn ich key und wert umdrehe, dann üsste man ja dem film ein zitat zuordnen, noch andersrum, oder?
Bin noch recht neu was dicts betrifft...
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Man könnte auch 2 Dicts nehmen:
- Name des Films in verschiedenen Varianten -> Kürzel
- Filmkürzel -> Zitat

Mit der Benutzereingabe wird dann zunächst das Filmkürzel ermittelt und anschließend geschaut ob das Kürzel zum Zitat passt.
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

Ahh, danke, soweit hab ich nicht gedacht...werd ich mal ausprobieren :-)
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

Also, ich gehe mal davon aus, du meintest sowas:

Code: Alles auswählen

 fn = {

        "Der Herr der Ringe": HDRN,
        "Herr der Ringe": HDRN

    }

 fz = {

        HDRN: HDR1,

    }
Wo und als was müsste ich HDRN dann definieren?
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich meinte das eher so in der Art:

Code: Alles auswählen

import random

movies = {'James Bond'        : 'JB',
          'Star Wars'         : 'SW',
          'Krieg der Sterne'  : 'SW',
          'Herr der Ringe'    : 'HDR',
          'Der Herr der Ringe': 'HDR'}

quotations = {'Du kannst nicht vorbei!': 'HDR',
              'Ich bin dein Vater!'    : 'SW',
              'Mein Name ist Bond.'    : 'JB'}

quote = random.choice(quotations)

print('Das Zitat:', quote)
answer = input('Zu welchem Film gehört es? ')

if movies[answer] == quotations[quote]:
    print('Richtig!')
Und um einen KeyError für unbekannte Filmbezeichnungen zu vermeiden, kann man die Abfrage auch ersetzen durch:

Code: Alles auswählen

if movies.get(answer) == quotations[quote]:
    print('Richtig!')
Dann gibt er None bei einem nicht vorhandenen Schlüssel zurück. Und ein Vergleich zwischen None und etwas anderem ist niemals wahr, außer wenn es mit sich selbst verglichen wird.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Da noch ein paar Fehler drin waren (kommt davon, wenn man nicht testet), hier noch etwas ordentlicher:

Code: Alles auswählen

import random

MOVIES = {'James Bond'        : 'JB',
          'Star Wars'         : 'SW',
          'Krieg der Sterne'  : 'SW',
          'Herr der Ringe'    : 'HDR',
          'Der Herr der Ringe': 'HDR'}

QUOTATIONS = {'Du kannst nicht vorbei!': 'HDR',
              'Ich bin dein Vater!'    : 'SW',
              'Mein Name ist Bond.'    : 'JB'}

def ask_quote():
    quote = random.choice(list(QUOTATIONS))
    print('Das Zitat:', quote)
    answer = input('Zu welchem Film gehört es? ')
    if MOVIES.get(answer) == QUOTATIONS[quote]:
        print('Richtig!')
    else:
        print('Leider falsch!')

def main():
    print('Willkommen zum ZITATERATEN!')
    while True:
        ask_quote()
        if input('Beliebige Taste zum Fortsetzen / "e" für Ende: ') == 'e':
            break
        print('Toll, nochmal! :-)')

if __name__ == '__main__':
    main()
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

Ok, vielen Dank fürs helfen... ich sehe, mein Problem lag darin dass ich den Kürzel immer als Var haben wollte, und ihn somit nie definiert habe...Manchmal denkt das Hirn einfach zu kompliziert...;)
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Sirius3
User
Beiträge: 17745
Registriert: Sonntag 21. Oktober 2012, 17:20

Was mich noch stören würde, sind die künstlichen Kürzel und dass Zitate und Filme nicht zusammenstehen.

Code: Alles auswählen

MOVIES_QUOTATIONS = [
    (['James Bond'], ['Mein Name ist Bond.']),
    (['Herr der Ringe', 'Der Herr der Ringe'], ['Du kannst nicht vorbei!']),
    (['Star Wars', 'Krieg der Sterne'], ['Ich bin dein Vater!', 'Möge die Macht mit Dir sein.']),
]

MOVIES = {m:mq for mq in MOVIES_QUOTATIONS for m in mq[0]}
QUOTATIONS = {q:mq for mq in MOVIES_QUOTATIONS for q in mq[1]}
Womit aber die beiden Wörterbücher überflüssig würden, weil man direkt einen Film zufällig aus der Liste auswählen könnte und gleich Zitat und Filmname in einem hätte:

Code: Alles auswählen

def ask_quote():
    names, quotes = random.choice(MOVIES_QUOTATIONS)
    print('Das Zitat:', random.choice(quotes))
    answer = input('Zu welchem Film gehört es? ')
    if answer in names:
        print('Richtig!')
    else:
        print('Leider falsch!')
Antworten