Получение ключа с максимальным значением в словаре?
у меня есть dictionary: ключи-это строки, значения-целые числа.
пример:
stats = {'a':1000, 'b':3000, 'c': 100}
Я хотел бы получить 'b' как ответ, так как это ключ с более высоким значением.
Я сделал следующее, используя промежуточный список с обратными кортежами ключ-значение:
inverse = [(value, key) for key, value in stats.items()]
print max(inverse)[1]
Это один из лучших (или даже более элегантный) подход?
19 ответов:
можно использовать
operator.itemgetterдля этого:import operator stats = {'a':1000, 'b':3000, 'c': 100} max(stats.iteritems(), key=operator.itemgetter(1))[0]и вместо построения нового списка в памяти используйте
stats.iteritems(). Элемент доmax()функция-это функция, которая вычисляет ключ, который используется для определения того, как ранжировать элементы.обратите внимание, что если бы у вас была другая пара ключ-значение 'd': 3000, что этот метод будет возвращать только один на два даже если они оба имеют максимальное значение.
>>> import operator >>> stats = {'a':1000, 'b':3000, 'c': 100, 'd':3000} >>> max(stats.iteritems(), key=operator.itemgetter(1))[0] 'b'при использовании Python3:
>>> max(stats.items(), key=operator.itemgetter(1))[0] 'b'
я протестировал много вариантов, и это самый быстрый способ вернуть ключ dict с максимальным значением:
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))]чтобы дать вам представление, вот некоторые методы кандидату:
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)тест словарь:
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}и результаты теста под 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% --и под 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% --видно, что
f1является самым быстрым под Python 3.2 и 2.7 (или, более полно,keywithmaxvalв верхней части этот пост)
Если вам нужно знать только ключ с максимальным значением вы можете сделать это без
iterkeysилиiteritemsпотому что итерация через словарь в Python-это итерация через его ключи.max_key = max(stats, key=lambda k: stats[k])EDIT:
из комментариев, @user1274878 :
Я новичок в python. Не могли бы вы объяснить свой ответ в шагах?
да...
Макс
max(iterable[, ключ])
max (arg1, arg2, *args [, key])
возвращает самый большой элемент в iterable или самый большой из двух или более аргументов.
необязательный элемент
keyаргумент описывает, как сравнить элементы, чтобы получить максимум среди них:lambda <item>: return <a result of operation with item>возвращаемые значения будут сравниваться.
дикт
в Python dict-это хэш-таблица. Ключ dict-это хэш объекта, объявленного в качестве ключа. Из-за производительности итерация, хотя дикт реализован как итерация через его ключи.
мы можем использовать его, чтобы избавиться от операции получения списка ключей.закрытие
функция определена внутри другой функции, называется вложенной функцией. Вложенные функции могут обращаться к переменным заключающей области.
The
statsпеременная доступна через наlambdaфункции как указатель на значение переменной определяется в родительской области.
вот еще один:
stats = {'a':1000, 'b':3000, 'c': 100} max(stats.iterkeys(), key=lambda k: stats[k])функции
keyпросто возвращает значение, которое должно использоваться для ранжирования иmax()возвращает требуемый элемент сразу.
key, value = max(stats.iteritems(), key=lambda x:x[1])Если вы не заботитесь о стоимости (я был бы удивлен, но) вы можете сделать:
key, _ = max(stats.iteritems(), key=lambda x:x[1])мне нравится кортеж распаковки лучше, чем [0] индекс в конце выражения. Мне никогда не нравилась читаемость лямбда-выражений, но найти этот лучше, чем оператор.itemgetter (1) IMHO.
учитывая, что более одной записи my имеют максимальное значение. Я бы сделал список ключей, которые имеют максимальное значение в качестве их значения.
>>> 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']Это даст вам " B " и любой другой максимальный ключ, а также.
Примечание: для python 3 Используйте
stats.items()вместоstats.iteritems()
чтобы получить максимальный ключ / значение словаря
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)конечно, если вы хотите получить только ключ или значение из результата, вы можете использовать индексирование кортежа. Например, чтобы получить ключ, соответствующий максимуму значение:
>>> max(stats.items(), key = lambda x: x[1])[0] 'b'объяснение
метод словарь
items()в Python 3 возвращает a вид объекта словаря. Когда этот объект представления повторяется, с помощьюmaxфункция, она дает элементы словаря в виде кортежей формы(key, value).
>>> list(stats.items()) [('c', 100), ('b', 3000), ('a', 1000)]при использовании
lambdaвыражениеlambda x: x[1]в каждой итерации,xis один из этих кортежей(key, value). Таким образом, выбирая правильный индекс, вы выбираете, хотите ли вы сравнивать по ключам или по значениям.Python 2
для Python 2.2 + релизы, тот же код будет работать. Однако, лучше использовать
iteritems()метод словаря вместоitems()для исполнения.Примечания
этот ответ основан на комментариях Climbs_lika_spyder's answer.
используемый код был протестирован на Python 3.5.2 и Python 2.7.10 .
за повторенные решения через комментарии в выбранном ответе...
В Python 3:
max(stats.keys(), key=(lambda k: stats[k]))В Python 2:
max(stats.iterkeys(), key=(lambda k: stats[k]))
С
collections.Counterвы могли бы сделать>>> import collections >>> stats = {'a':1000, 'b':3000, 'c': 100} >>> stats = collections.Counter(stats) >>> stats.most_common(1) [('b', 3000)]при необходимости, вы можете просто начать с пустого
collections.Counterи добавить к нему>>> stats = collections.Counter() >>> stats['a'] += 1 : etc.
Спасибо, очень элегантный, я не помню, что Макс позволяет "ключевой параметр".
кстати, чтобы получить правильный ответ ('b'), он должен быть:
import operator stats = {'a':1000, 'b':3000, 'c': 100} max(stats.iteritems(), key=operator.itemgetter(1))[0]
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')
+1 к @Aric Coadyсамое простое решение.
А также один из способов случайного выбора одного из ключей с максимальным значением в словаре: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])
пример:
stats = {'a':1000, 'b':3000, 'c': 100}Если вы хотите найти максимальное значение с его ключом, возможно, follwing может быть простым, без каких-либо соответствующих функций.
max(stats, key=stats.get)выход-это ключ, который имеет максимальное значение.
Я пришел сюда в поисках того, как вернуться
mydict.keys()исходя из стоимостиmydict.values(). Вместо того, чтобы просто один ключ вернулся, я искал, чтобы вернуть верхнюю x количество значений.такое решение проще, чем с помощью
max()функция и вы можете легко изменить количество возвращенных значений:stats = {'a':1000, 'b':3000, 'c': 100} x = sorted(stats, key=(lambda key:stats[key]), reverse=True) ['b', 'a', 'c']если вы хотите один самый высокий рейтинг ключ, просто используйте индекс:
x[0] ['b']если вы хотите, чтобы два самых высоких ключа рейтинга, просто используйте список нарезки:
x[:2] ['b', 'a']
Я проверил принятый ответ и самое быстрое решение @thewolf против очень простого цикла, и цикл был быстрее, чем оба:
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))результаты:
Iterating: 3.8201940059661865 List creating: 6.928712844848633 Accepted answer: 5.464320182800293
Comments