Alle Schlüssel mit höchstem Wert im `dict()` 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
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Hallo

Ich habe mir wieder eine kleine Übungsaufgabe ausgedacht. Diesmal gibt es ein `dict()` mit Buchstaben als Schlüssel (z.B. "a") und Zahlen als Werte (z.B. 10).

In einer Liste sollen nun alle Schlüssel ausgegeben werden, die den höchsten Zahlenwert im Wörterbuch haben.

Code:

Code: Alles auswählen

pairs = {"a": 10,
         "b": 43,
         "c": 45,
         "d": 67,
         "e": 23,
         "f": 45,
         "g": 34,
         "h": 54,
         "i": 34,
         "j": 32,
         "k": 75,  # höchster Wert
         "l": 67,
         "m": 34,
         "n": 45,
         "o": 34,
         "p": 23,
         "q": 67,
         "r": 75,  # höchster Wert
         "s": 67,
         "t": 34,
         "u": 46,
         "v": 33,
         "w": 54,
         "x": 45,
         "y": 56,
         "z": 43}


def find_keys_with_highest_value(data):
    result = dict()
    for key, value in data.items():
        if not result.get(str(value)):
            result[str(value)] = list()
        result[str(value)].append(key)
    maximum_value = max(result.keys())
    return result[maximum_value]


print(find_keys_with_highest_value(pairs))
Ausgabe:

Code: Alles auswählen

['k', 'r']
Was haltet ihr von meiner Lösung?

Gruß
Atalanttore
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum wandelst Du Zahlen in Strings um? Da hast Du Glück, dass alle Zahlen zwei Ziffern haben. Außerdem musst Du Dir ja nicht alles merken, es reicht, die größte Zahl und die Keys dazu zu speichern. Wird eine größere Zahl gefunden, einfach wieder mit einer leeren Liste anfangen.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Ungefähr so:

Code: Alles auswählen

def find_keys_with_highest_value(data):
    result = None
    highest_value = float('-inf')
    for key, value in data.items():
        if highest_value <= value:
            if highest_value < value:
                highest_value = value
                result = []
            result.append(key)
    return result
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

@Sirius3: Danke für deinen verbesserten Code.

Als Schlüssel kann man auch Integer nehmen.
Sirius3 hat geschrieben: Sonntag 17. November 2019, 22:32 Da hast Du Glück, dass alle Zahlen zwei Ziffern haben.
Was meinst du damit genau?

Was bedeutet `float('-inf')`?

Gruß
Atalanttore
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Geht auch kürzer:

Code: Alles auswählen

highest = max(pairs.values())
print([key for key in pairs if pairs[key] == highest])
Und falls nur ein Schlüssel gefragt wäre:

Code: Alles auswählen

print(max(pairs, key=pairs.get))
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

@snafu: Danke für den Code.

Erst mit `max()` den höchsten Wert im Dictionary suchen und anschließend alle Schlüssel ausgeben, die diesen höchsten Wert haben. Eigentlich ganz logisch und einfach. :)

Gruß
Atalanttore
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Atalanttore: Man kann als Schlüssel alles nehmen was ”hashable” ist und den ”Vertrag” zusammen mit der Vergleichsoperation erfüllt, dass aus ``a == b`` folgt das auch ``hash(a) == hash(b)`` gilt.

Du hast Glück das alle Zahlen die gleiche Anzahl von Ziffern haben weil der kleiner/grösser-Vergleich von Zeichenketten sonst nicht so funktioniert wie Du das gerne hättest, weil dann nicht der Zahlwert verglichen wird, sondern die Zeichenketten:

Code: Alles auswählen

In [154]: 2 < 10                                                                
Out[154]: True

In [155]: "2" < "10"                                                            
Out[155]: False
Die Frage zu ``float("-inf")`` sollte die Dokumentation beantworten können: https://docs.python.org/3.6/library/fun ... html#float

Hätte man auch mit der Konstante aus dem `math`-Modul als ``-math.inf`` schreiben können.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

@__blackjack__: Danke für die genaue Erklärung. Jetzt habe ich das Problem verstanden.

Der Begriff ”hashable” begegnet mir häufig bei Fehlermeldungen. Aus dem Python Glossar wird mir aber nicht klar, warum man bzw. Python so etwas überhaupt benötigt.

Was meinst du mit ”Vertrag”?

Gruß
Atalanttore
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ein Vertrag ist eine Vereinbarung zwischen zwei oder mehr Parteien. Und in diesem Fall ist eine das dict, und die andere eine hash-Funktion, die sich eben auf bestimmte Art zu benehmen hat.
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

@__deets__: Wieder was gelernt. Danke. "Verträge" sind mir bei Python bisher noch nie begegnet.

Gruß
Atalanttore
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist ja auch nichts formales, sondern ein Konzept. Es gibt tatsaechlich formalere Umsetzungen wie "design by contract", die eben ein solches Verhalten auch noch etwas konkreter machen. Aber allgemeiner sagt man eben nur damit aus, dass man sich auf bestimmte Weise verhalten muss. Jenseits von zB Methodennamen und Argumenten.
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

"design by contract" kannte ich auch noch nicht.
Antworten