Получение ключа с максимальным значением в словаре?



у меня есть dictionary: ключи-это строки, значения-целые числа.



пример:



stats = {'a':1000, 'b':3000, 'c': 100}


Я хотел бы получить 'b' как ответ, так как это ключ с более высоким значением.



Я сделал следующее, используя промежуточный список с обратными кортежами ключ-значение:



inverse = [(value, key) for key, value in stats.items()]
print max(inverse)[1]


Это один из лучших (или даже более элегантный) подход?

614   19  

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'
max(stats, key=stats.get)

я протестировал много вариантов, и это самый быстрый способ вернуть ключ 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] в каждой итерации, x is один из этих кортежей (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')

max((value, key) for key, value in stats.items())[1]

+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']
Counter = 0
for word in stats.keys():
    if stats[word]> counter:
        Counter = stats [word]
print Counter

Я проверил принятый ответ и самое быстрое решение @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

Как насчет:

 max(zip(stats.keys(), stats.values()), key=lambda t : t[1])[0]

Comments

    Ничего не найдено.