Ich habe eine dictionary
: Schlüssel sind Strings, Werte sind ganze Zahlen.
Beispiel:
stats = {'a':1000, 'b':3000, 'c': 100}
Ich möchte 'b'
als Antwort erhalten, da dies der Schlüssel mit einem höheren Wert ist.
Ich habe folgende Schritte ausgeführt und eine Zwischenliste mit umgekehrten Schlüsselwerttupeln verwendet:
inverse = [(value, key) for key, value in stats.items()]
print max(inverse)[1]
Ist das der bessere (oder noch elegantere) Ansatz?
Sie können operator.itemgetter
dafür verwenden:
import operator
stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iteritems(), key=operator.itemgetter(1))[0]
Und anstatt eine neue Liste im Speicher zu erstellen, verwenden Sie stats.iteritems()
. Der key
-Parameter der max()
-Funktion ist eine Funktion, die einen Schlüssel berechnet, der zum Bestimmen der Rangfolge von Elementen verwendet wird.
Wenn Sie ein anderes Schlüsselwertpaar 'd': 3000 haben, gibt diese Methode nur eins der zwei zurück, obwohl beide den Maximalwert haben.
>>> import operator
>>> stats = {'a':1000, 'b':3000, 'c': 100, 'd':3000}
>>> max(stats.iteritems(), key=operator.itemgetter(1))[0]
'b'
Wenn Sie Python3 verwenden:
>>> max(stats.items(), key=operator.itemgetter(1))[0]
'b'
max(stats, key=stats.get)
Ich habe VIELE Varianten getestet, und dies ist der schnellste Weg, um den Schlüssel von dict mit dem maximalen Wert zurückzugeben:
def keywithmaxval(d):
""" a) create a list of the dict's keys and values;
b) return the key with the max value"""
v=list(d.values())
k=list(d.keys())
return k[v.index(max(v))]
Um Ihnen eine Idee zu geben, hier einige Kandidatenmethoden:
def f1():
v=list(d1.values())
k=list(d1.keys())
return k[v.index(max(v))]
def f2():
d3={v:k for k,v in d1.items()}
return d3[max(d3)]
def f3():
return list(filter(lambda t: t[1]==max(d1.values()), d1.items()))[0][0]
def f3b():
# same as f3 but remove the call to max from the lambda
m=max(d1.values())
return list(filter(lambda t: t[1]==m, d1.items()))[0][0]
def f4():
return [k for k,v in d1.items() if v==max(d1.values())][0]
def f4b():
# same as f4 but remove the max from the comprehension
m=max(d1.values())
return [k for k,v in d1.items() if v==m][0]
def f5():
return max(d1.items(), key=operator.itemgetter(1))[0]
def f6():
return max(d1,key=d1.get)
def f7():
""" a) create a list of the dict's keys and values;
b) return the key with the max value"""
v=list(d1.values())
return list(d1.keys())[v.index(max(v))]
def f8():
return max(d1, key=lambda k: d1[k])
tl=[f1,f2, f3b, f4b, f5, f6, f7, f8, f4,f3]
cmpthese.cmpthese(tl,c=100)
Das Testwörterbuch:
d1={1: 1, 2: 2, 3: 8, 4: 3, 5: 6, 6: 9, 7: 17, 8: 4, 9: 20, 10: 7, 11: 15,
12: 10, 13: 10, 14: 18, 15: 18, 16: 5, 17: 13, 18: 21, 19: 21, 20: 8,
21: 8, 22: 16, 23: 16, 24: 11, 25: 24, 26: 11, 27: 112, 28: 19, 29: 19,
30: 19, 3077: 36, 32: 6, 33: 27, 34: 14, 35: 14, 36: 22, 4102: 39, 38: 22,
39: 35, 40: 9, 41: 110, 42: 9, 43: 30, 44: 17, 45: 17, 46: 17, 47: 105, 48: 12,
49: 25, 50: 25, 51: 25, 52: 12, 53: 12, 54: 113, 1079: 50, 56: 20, 57: 33,
58: 20, 59: 33, 60: 20, 61: 20, 62: 108, 63: 108, 64: 7, 65: 28, 66: 28, 67: 28,
68: 15, 69: 15, 70: 15, 71: 103, 72: 23, 73: 116, 74: 23, 75: 15, 76: 23, 77: 23,
78: 36, 79: 36, 80: 10, 81: 23, 82: 111, 83: 111, 84: 10, 85: 10, 86: 31, 87: 31,
88: 18, 89: 31, 90: 18, 91: 93, 92: 18, 93: 18, 94: 106, 95: 106, 96: 13, 9232: 35,
98: 26, 99: 26, 100: 26, 101: 26, 103: 88, 104: 13, 106: 13, 107: 101, 1132: 63,
2158: 51, 112: 21, 113: 13, 116: 21, 118: 34, 119: 34, 7288: 45, 121: 96, 122: 21,
124: 109, 125: 109, 128: 8, 1154: 32, 131: 29, 134: 29, 136: 16, 137: 91, 140: 16,
142: 104, 143: 104, 146: 117, 148: 24, 149: 24, 152: 24, 154: 24, 155: 86, 160: 11,
161: 99, 1186: 76, 3238: 49, 167: 68, 170: 11, 172: 32, 175: 81, 178: 32, 179: 32,
182: 94, 184: 19, 31: 107, 188: 107, 190: 107, 196: 27, 197: 27, 202: 27, 206: 89,
208: 14, 214: 102, 215: 102, 220: 115, 37: 22, 224: 22, 226: 14, 232: 22, 233: 84,
238: 35, 242: 97, 244: 22, 250: 110, 251: 66, 1276: 58, 256: 9, 2308: 33, 262: 30,
263: 79, 268: 30, 269: 30, 274: 92, 1300: 27, 280: 17, 283: 61, 286: 105, 292: 118,
296: 25, 298: 25, 304: 25, 310: 87, 1336: 71, 319: 56, 322: 100, 323: 100, 325: 25,
55: 113, 334: 69, 340: 12, 1367: 40, 350: 82, 358: 33, 364: 95, 376: 108,
377: 64, 2429: 46, 394: 28, 395: 77, 404: 28, 412: 90, 1438: 53, 425: 59, 430: 103,
1456: 97, 433: 28, 445: 72, 448: 23, 466: 85, 479: 54, 484: 98, 485: 98, 488: 23,
6154: 37, 502: 67, 4616: 34, 526: 80, 538: 31, 566: 62, 3644: 44, 577: 31, 97: 119,
592: 26, 593: 75, 1619: 48, 638: 57, 646: 101, 650: 26, 110: 114, 668: 70, 2734: 41,
700: 83, 1732: 30, 719: 52, 728: 96, 754: 65, 1780: 74, 4858: 47, 130: 29, 790: 78,
1822: 43, 2051: 38, 808: 29, 850: 60, 866: 29, 890: 73, 911: 42, 958: 55, 970: 99,
976: 24, 166: 112}
Und die Testergebnisse unter Python 3.2:
rate/sec f4 f3 f3b f8 f5 f2 f4b f6 f7 f1
f4 454 -- -2.5% -96.9% -97.5% -98.6% -98.6% -98.7% -98.7% -98.9% -99.0%
f3 466 2.6% -- -96.8% -97.4% -98.6% -98.6% -98.6% -98.7% -98.9% -99.0%
f3b 14,715 3138.9% 3057.4% -- -18.6% -55.5% -56.0% -56.4% -58.3% -63.8% -68.4%
f8 18,070 3877.3% 3777.3% 22.8% -- -45.4% -45.9% -46.5% -48.8% -55.5% -61.2%
f5 33,091 7183.7% 7000.5% 124.9% 83.1% -- -1.0% -2.0% -6.3% -18.6% -29.0%
f2 33,423 7256.8% 7071.8% 127.1% 85.0% 1.0% -- -1.0% -5.3% -17.7% -28.3%
f4b 33,762 7331.4% 7144.6% 129.4% 86.8% 2.0% 1.0% -- -4.4% -16.9% -27.5%
f6 35,300 7669.8% 7474.4% 139.9% 95.4% 6.7% 5.6% 4.6% -- -13.1% -24.2%
f7 40,631 8843.2% 8618.3% 176.1% 124.9% 22.8% 21.6% 20.3% 15.1% -- -12.8%
f1 46,598 10156.7% 9898.8% 216.7% 157.9% 40.8% 39.4% 38.0% 32.0% 14.7% --
Und unter Python 2.7:
rate/sec f3 f4 f8 f3b f6 f5 f2 f4b f7 f1
f3 384 -- -2.6% -97.1% -97.2% -97.9% -97.9% -98.0% -98.2% -98.5% -99.2%
f4 394 2.6% -- -97.0% -97.2% -97.8% -97.9% -98.0% -98.1% -98.5% -99.1%
f8 13,079 3303.3% 3216.1% -- -5.6% -28.6% -29.9% -32.8% -38.3% -49.7% -71.2%
f3b 13,852 3504.5% 3412.1% 5.9% -- -24.4% -25.8% -28.9% -34.6% -46.7% -69.5%
f6 18,325 4668.4% 4546.2% 40.1% 32.3% -- -1.8% -5.9% -13.5% -29.5% -59.6%
f5 18,664 4756.5% 4632.0% 42.7% 34.7% 1.8% -- -4.1% -11.9% -28.2% -58.8%
f2 19,470 4966.4% 4836.5% 48.9% 40.6% 6.2% 4.3% -- -8.1% -25.1% -57.1%
f4b 21,187 5413.0% 5271.7% 62.0% 52.9% 15.6% 13.5% 8.8% -- -18.5% -53.3%
f7 26,002 6665.8% 6492.4% 98.8% 87.7% 41.9% 39.3% 33.5% 22.7% -- -42.7%
f1 45,354 11701.5% 11399.0% 246.8% 227.4% 147.5% 143.0% 132.9% 114.1% 74.4% --
Sie sehen, dass f1
unter Python 3.2 und 2.7 der schnellste ist (oder keywithmaxval
ganz oben in diesem Beitrag).
Wenn Sie nur einen Schlüssel mit dem maximalen Wert benötigen, können Sie dies ohne iterkeys
oder iteritems
tun, da die Iteration durch das Wörterbuch in Python die Iteration durch die Schlüssel ist.
max_key = max(stats, key=lambda k: stats[k])
BEARBEITEN:
Aus den Kommentaren, @ user1274878:
Ich bin neu im Python. Kannst du bitte deine Antwort in Schritten erklären?
Ja...
max (iterable [ key])
max (arg1, arg2, * args [ Schlüssel])
Gibt das größte Element in einem iterierbaren oder das größte von zwei oder mehr Argumenten zurück.
Das optionale Argument key
beschreibt, wie Elemente miteinander verglichen werden, um ein Maximum zwischen ihnen zu erhalten:
lambda <item>: return <a result of operation with item>
Zurückgegebene Werte werden verglichen.
Python-Dikt ist eine Hashtabelle. Ein Schlüssel eines Diktiers ist ein Hash eines als Schlüssel deklarierten Objekts. Aus Leistungsgründen wurde die Iteration durch ein Dict durch ihre Schlüssel implementiert.
Daher können wir es verwenden, um die Erstellung einer Schlüsselliste zu beenden.
Eine in einer anderen Funktion definierte Funktion wird als verschachtelte Funktion bezeichnet. Verschachtelte Funktionen können auf Variablen des umschließenden Bereichs zugreifen.
Die Variable stats
, die über das Attribut __closure__
der Funktion lambda
verfügbar ist, als Zeiger auf den Wert der im übergeordneten Bereich definierten Variablen.
Hier ist noch einer:
stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iterkeys(), key=lambda k: stats[k])
Die Funktion key
gibt einfach den Wert zurück, der für das Ranking verwendet werden soll, und max()
gibt das geforderte Element sofort zurück.
key, value = max(stats.iteritems(), key=lambda x:x[1])
Wenn Sie sich nicht für den Wert interessieren (ich wäre überrascht, aber), können Sie Folgendes tun:
key, _ = max(stats.iteritems(), key=lambda x:x[1])
Ich mag das Tuple-Auspacken besser als ein [0] -Zeichenwert am Ende des Ausdrucks. Ich mag die Lesbarkeit von Lambda-Ausdrücken nie sehr, aber finde diesen besser als den Operator.itemgetter (1) IMHO.
Da mehr als ein Eintrag den Maximalwert haben kann. Ich würde eine Liste der Schlüssel erstellen, die den Maximalwert als ihren Wert haben.
>>> stats = {'a':1000, 'b':3000, 'c': 100, 'd':3000}
>>> [key for m in [max(stats.values())] for key,val in stats.iteritems() if val == m]
['b', 'd']
Dadurch erhalten Sie 'b' und alle anderen max-Tasten.
Hinweis: Für Python 3 verwenden Sie stats.items()
anstelle von stats.iteritems()
.
Um den maximalen Schlüssel/Wert des Wörterbuchs zu erhalten, stats
:
stats = {'a':1000, 'b':3000, 'c': 100}
>>> max(stats.items(), key = lambda x: x[0])
('c', 100)
>>> max(stats.items(), key = lambda x: x[1])
('b', 3000)
Wenn Sie nur den Schlüssel oder Wert aus dem Ergebnis erhalten möchten, können Sie natürlich die Tuple-Indizierung verwenden. Um beispielsweise den Schlüssel zu erhalten, der dem Maximalwert entspricht:
>>> max(stats.items(), key = lambda x: x[1])[0]
'b'
Erklärung
Die Wörterbuchmethode items()
in Python 3 gibt ein view-Objekt des Wörterbuchs zurück. Wenn dieses Ansichtsobjekt durch die Funktion max
durchlaufen wird, werden die Wörterbuchelemente als Tupel der Form (key, value)
ausgegeben.
>>> list(stats.items())
[('c', 100), ('b', 3000), ('a', 1000)]
Wenn Sie den lambda
Ausdruck lambda x: x[1]
verwenden, ist x
in jeder Iteration einer dieser Tupel (key, value)
. Wenn Sie also den richtigen Index auswählen, wählen Sie aus, ob Sie nach Schlüsseln oder nach Werten vergleichen möchten.
Python 2
Bei Python 2.2 und höheren Versionen funktioniert derselbe Code. Es ist jedoch besser, die iteritems()
dictionary-Methode anstelle von items()
für die Leistung zu verwenden.
Anmerkungen
Diese Antwort basiert auf den Kommentaren zu Climbs_lika_Spyder's Antwort .
Der verwendete Code wurde auf Python 3.5.2 und Python 2.7.10 getestet.
Beispiel:
stats = {'a':1000, 'b':3000, 'c': 100}
wenn Sie den maximalen Wert mit seiner Taste finden möchten, könnte das Folgen einfach sein, ohne relevante Funktionen.
max(stats, key=stats.get)
die Ausgabe ist der Schlüssel mit dem maximalen Wert.
d = {'A': 4,'B':10}
min_v = min(Zip(d.values(), d.keys()))
# min_v is (4,'A')
max_v = max(Zip(d.values(), d.keys()))
# max_v is (10,'B')
Für die iterierten Lösungen über Kommentare in der ausgewählten Antwort ...
In Python 3:
max(stats.keys(), key=(lambda k: stats[k]))
In Python 2:
max(stats.iterkeys(), key=(lambda k: stats[k]))
Mit collections.Counter
geht das
>>> import collections
>>> stats = {'a':1000, 'b':3000, 'c': 100}
>>> stats = collections.Counter(stats)
>>> stats.most_common(1)
[('b', 3000)]
Gegebenenfalls können Sie einfach mit einem leeren collections.Counter
beginnen und diesen hinzufügen
>>> stats = collections.Counter()
>>> stats['a'] += 1
:
etc.
Danke, sehr elegant, ich konnte mich nicht erinnern, dass max einen "Schlüssel" -Parameter erlaubt.
BTW, um die richtige Antwort ('b') zu erhalten, muss es sein:
import operator
stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iteritems(), key=operator.itemgetter(1))[0]
Ich habe hier nach dem Rückgabewert von mydict.keys()
gesucht, basierend auf dem Wert von mydict.values()
. Anstelle nur eines Schlüssels, der zurückgegeben wurde, wollte ich die obersten x - Anzahl von Werten zurückgeben.
Diese Lösung ist einfacher als die Verwendung der Funktion max()
. Sie können die Anzahl der zurückgegebenen Werte einfach ändern:
stats = {'a':1000, 'b':3000, 'c': 100}
x = sorted(stats, key=(lambda key:stats[key]), reverse=True)
['b', 'a', 'c']
Wenn Sie den einzigen Schlüssel mit dem höchsten Rang wünschen, verwenden Sie einfach den Index:
x[0]
['b']
Wenn Sie die obersten zwei Schlüssel mit dem höchsten Rang wünschen, verwenden Sie einfach das Listen-Slicing:
x[:2]
['b', 'a']
max((value, key) for key, value in stats.items())[1]
Counter = 0
for Word in stats.keys():
if stats[Word]> counter:
Counter = stats [Word]
print Counter
+1 zu @Aric Coady s einfachste Lösung.
Und auch eine Möglichkeit, einen der Schlüssel mit maximalem Wert im Wörterbuch zufällig auszuwählen:
stats = {'a':1000, 'b':3000, 'c': 100, 'd':3000}
import random
maxV = max(stats.values())
# Choice is one of the keys with max value
choice = random.choice([key for key, value in stats.items() if value == maxV])
Mit keiner dieser Antworten war ich zufrieden. max
wählt immer den ersten Schlüssel mit dem Maximalwert. Das Wörterbuch kann mehrere Schlüssel mit diesem Wert enthalten.
def keys_with_top_values(my_dict):
return [key for (key, value) in my_dict.items() if value == max(my_dict.values())]
Posten Sie diese Antwort, falls sie jemandem hilft. Siehe den folgenden SO Beitrag
Wie wäre es mit:
max(Zip(stats.keys(), stats.values()), key=lambda t : t[1])[0]
Ich habe die akzeptierte Antwort von AND @ thewolf gegen eine sehr einfache Schleife getestet und die Schleife war schneller als beide:
import time
import operator
d = {"a"+str(i): i for i in range(1000000)}
def t1(dct):
mx = float("-inf")
key = None
for k,v in dct.items():
if v > mx:
mx = v
key = k
return key
def t2(dct):
v=list(dct.values())
k=list(dct.keys())
return k[v.index(max(v))]
def t3(dct):
return max(dct.items(),key=operator.itemgetter(1))[0]
start = time.time()
for i in range(25):
m = t1(d)
end = time.time()
print ("Iterating: "+str(end-start))
start = time.time()
for i in range(25):
m = t2(d)
end = time.time()
print ("List creating: "+str(end-start))
start = time.time()
for i in range(25):
m = t3(d)
end = time.time()
print ("Accepted answer: "+str(end-start))
ergebnisse:
Iterating: 3.8201940059661865
List creating: 6.928712844848633
Accepted answer: 5.464320182800293
Eine Heap-Warteschlange ist eine generalized -Lösung, mit der Sie die obersten n -Tasten nach Wert geordnet extrahieren können:
from heapq import nlargest
stats = {'a':1000, 'b':3000, 'c': 100}
res1 = nlargest(1, stats, key=stats.__getitem__) # ['b']
res2 = nlargest(2, stats, key=stats.__getitem__) # ['b', 'a']
res1_val = next(iter(res1)) # 'b'
Hinweis dict.__getitem__
ist die Methode, die vom syntaktischen Zucker dict[]
aufgerufen wird. Im Gegensatz zu dict.get
wird KeyError
zurückgegeben, wenn kein Schlüssel gefunden wird, der hier nicht vorkommt.