Uzyskanie klucza o maksymalnej wartości w słowniku?
Mam dictionary
: klucze są ciągami znaków, wartości są liczbami całkowitymi.
Przykład:
stats = {'a':1000, 'b':3000, 'c': 100}
Chciałbym otrzymać 'b'
jako odpowiedź, ponieważ jest to klucz o wyższej wartości.
Zrobiłem co następuje, używając listy pośredniej z odwróconymi krotkami o wartości klucza:
inverse = [(value, key) for key, value in stats.items()]
print max(inverse)[1]
Czy to lepsze (a nawet bardziej eleganckie) podejście?
19 answers
Możesz użyć operator.itemgetter
do tego:
import operator
stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iteritems(), key=operator.itemgetter(1))[0]
I zamiast budowania nowej listy w pamięci użyj stats.iteritems()
. Parametr key
do funkcji max()
jest funkcją, która oblicza klucz, który jest używany do określania rangi elementów.
Zwróć uwagę, że jeśli masz inną parę klucz-wartość 'd': 3000, ta metoda zwróci tylko jedną z dwóch, nawet jeśli obie mają wartość maksymalną.
>>> import operator
>>> stats = {'a':1000, 'b':3000, 'c': 100, 'd':3000}
>>> max(stats.iteritems(), key=operator.itemgetter(1))[0]
'b'
Jeśli używasz Python3:
>>> max(stats.items(), key=operator.itemgetter(1))[0]
'b'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 17:51:35
max(stats, key=stats.get)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-11 06:24:30
Przetestowałem wiele wariantów i jest to najszybszy sposób na zwrócenie klucza dict z wartością maksymalną:
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))]
Aby dać ci pomysł, oto kilka metod kandydowania:
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)
Słownik testowy:
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}
I wyniki testów w Pythonie 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% --
I pod Pythonem 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% --
Widać, że f1
jest najszybszy pod Pythonem 3.2 i 2.7 (a dokładniej {[6] } u góry tego posta)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 00:05:54
Jeśli potrzebujesz znać tylko klucz o maksymalnej wartości, możesz to zrobić bez iterkeys
lub iteritems
, ponieważ iteracja przez słownik w Pythonie jest iteracją przez jego klucze.
max_key = max(stats, key=lambda k: stats[k])
EDIT:
z komentarzy, @ user1274878:
Tak...Jestem nowy w Pythonie. Czy możesz wyjaśnić swoją odpowiedź krok po kroku?
Max
Max (iterable [, key])
Max (arg1, arg2, * args [, klucz])
Return największy element w iterowalnym lub największy z dwóch lub więcej argumentów.
Opcjonalny argument key
opisuje jak porównać elementy, aby uzyskać maksimum między nimi:
lambda <item>: return <a result of operation with item>
Zwrócone wartości zostaną porównane.
Dict
Python dict jest tabelą hash. Klucz dict to hash obiektu zadeklarowanego jako klucz. Ze względu na wydajność iteracji choć dict zaimplementowane jako iteracji poprzez jego klucze.
Dlatego możemy go użyć do pozbycia się operacji uzyskanie listy kluczy.
Zamknięcie
Funkcja zdefiniowana wewnątrz innej funkcji nazywana jest funkcją zagnieżdżoną. Zagnieżdżone funkcje mogą uzyskać dostęp do zmiennych z zakresu zamykającego.
Zmienna stats
dostępna poprzez atrybut __closure__
funkcji lambda
jako wskaźnik do wartości zmiennej zdefiniowanej w zakresie nadrzędnym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-21 06:12:49
Oto kolejny:
stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iterkeys(), key=lambda k: stats[k])
Funkcja key
po prostu zwraca wartość, która powinna być użyta do rankingu i max()
zwraca żądany element od razu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-26 22:09:04
key, value = max(stats.iteritems(), key=lambda x:x[1])
Jeśli nie zależy ci na wartości (byłbym zaskoczony, ale) możesz zrobić:
key, _ = max(stats.iteritems(), key=lambda x:x[1])
Lubię rozpakowywanie krotki lepiej niż [0] indeks dolny na końcu wyrażenia. Nigdy nie podoba mi się czytelność wyrażeń lambda bardzo, ale znaleźć ten lepszy niż operator.itemgetter(1) IMHO.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-30 18:39:59
Biorąc pod uwagę, że więcej niż jeden wpis mój ma wartość maksymalną. Chciałbym zrobić listę kluczy, które mają wartość maksymalną jako ich wartość.
>>> 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']
To da Ci 'b' i każdy inny klucz max.
Uwaga: dla Pythona 3 Użyj stats.items()
zamiast stats.iteritems()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-07 18:16:33
Aby uzyskać maksymalny klucz / wartość słownika stats
:
stats = {'a':1000, 'b':3000, 'c': 100}
- na podstawie kluczy
>>> max(stats.items(), key = lambda x: x[0])
('c', 100)
- na podstawie wartości
>>> max(stats.items(), key = lambda x: x[1])
('b', 3000)
Oczywiście, jeśli chcesz uzyskać tylko klucz lub wartość z wyniku, możesz użyć indeksowania krotki. Na przykład, aby uzyskać klucz odpowiadający maksymalnej wartości:
>>> max(stats.items(), key = lambda x: x[1])[0]
'b'
Wyjaśnienie
Metoda słownikowa items()
w Pythonie 3 zwraca obiekt widoku słownika. Gdy ten obiekt widoku jest iterowany przez funkcję max
, otrzymuje on pozycje słownika jako krotki postaci (key, value)
.
>>> list(stats.items())
[('c', 100), ('b', 3000), ('a', 1000)]
Kiedy używasz lambda
wyrażenie lambda x: x[1]
, w każdej iteracji x
jest jedną z tych krotek (key, value)
. Wybierając odpowiedni indeks, wybierasz, czy chcesz porównać według kluczy, czy według wartości.
Python 2
Dla wersji Python 2.2+ , ten sam kod zadziała. Jednak lepiej jest użyć iteritems()
metoda słownikowa zamiast items()
dla wydajności.
Uwagi
Ta odpowiedź jest oparta na komentarzach do odpowiedzi Climbs_lika_Spyder .
Użyty kod został przetestowany na Pythonie 3.5.2 i Pythonie 2.7.10 .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-17 11:28:09
Na rozwiązania iteracyjne poprzez komentarze w wybranej odpowiedzi...
W Pythonie 3:
max(stats.keys(), key=(lambda k: stats[k]))
W Pythonie 2:
max(stats.iterkeys(), key=(lambda k: stats[k]))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-05 02:03:11
With collections.Counter
you could do
>>> import collections
>>> stats = {'a':1000, 'b':3000, 'c': 100}
>>> stats = collections.Counter(stats)
>>> stats.most_common(1)
[('b', 3000)]
Jeśli to właściwe, możesz po prostu zacząć od pustego collections.Counter
i dodać do niego
>>> stats = collections.Counter()
>>> stats['a'] += 1
:
etc.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-23 18:58:38
Dzięki, bardzo eleganckie, nie pamiętam, że max pozwala na parametr "kluczowy".
BTW, aby uzyskać prawidłową odpowiedź ('b') musi być:
import operator
stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iteritems(), key=operator.itemgetter(1))[0]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-06 11:04:28
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')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-04 06:50:19
max((value, key) for key, value in stats.items())[1]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-10 05:32:18
+1 do @Aric Coady 's najprostsze rozwiązanie.
A także jeden sposób na losowe wybranie jednego z klawiszy o maksymalnej wartości w słowniku:
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])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-02 08:57:23
Przykład:
stats = {'a':1000, 'b':3000, 'c': 100}
Jeśli chcesz znaleźć wartość max z jej kluczem, może follwing może być prosty, bez żadnych istotnych funkcji.
max(stats, key=stats.get)
Wyjściem jest klucz, który ma wartość maksymalną.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-23 04:08:56
Dotarłem tutaj, szukając jak zwrócić mydict.keys()
na podstawie wartości mydict.values()
. Zamiast tylko jednego zwracanego klucza, chciałem zwrócić górną x liczbę wartości.
To rozwiązanie jest prostsze niż użycie funkcji max()
i można łatwo zmienić ilość zwracanych wartości:
stats = {'a':1000, 'b':3000, 'c': 100}
x = sorted(stats, key=(lambda key:stats[key]), reverse=True)
['b', 'a', 'c']
Jeśli chcesz mieć pojedynczy klucz najwyższej rangi, użyj indeksu:
x[0]
['b']
Jeśli chcesz mieć dwa najwyższe klucze rankingowe, po prostu użyj list slicing:
x[:2]
['b', 'a']
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-12 09:43:56
Counter = 0
for word in stats.keys():
if stats[word]> counter:
Counter = stats [word]
print Counter
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-26 12:31:42
Przetestowałem zaakceptowaną odpowiedź i najszybsze rozwiązanie @thewolf na bardzo podstawowej pętli i pętla była szybsza od obu:
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))
Wyniki:
Iterating: 3.8201940059661865
List creating: 6.928712844848633
Accepted answer: 5.464320182800293
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-11 16:26:24
A może:
max(zip(stats.keys(), stats.values()), key=lambda t : t[1])[0]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-04 20:34:57