Obtenir la clé avec la valeur maximale dans le dictionnaire?

j'ai un dictionary : les clés sont des chaînes, les valeurs sont des entiers.

exemple:

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

j'aimerais avoir 'b' comme réponse, puisque c'est la clé avec une valeur plus élevée.

j'ai fait ce qui suit, en utilisant une liste intermédiaire avec des tuples de valeurs clés inversées:

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

est-ce là une approche meilleure (ou encore plus élégante)?

563
demandé sur Darshana 2008-11-06 13:49:58

19 réponses

vous pouvez utiliser operator.itemgetter pour cela:

import operator
stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iteritems(), key=operator.itemgetter(1))[0]

et au lieu de construire une nouvelle liste en mémoire, utilisez stats.iteritems() . Le paramètre key de la fonction max() est une fonction qui calcule une clé qui est utilisée pour déterminer comment classer les éléments.

veuillez noter que si vous deviez avoir une autre paire de clés 'd': 3000, cette méthode ne retournera que un des deux même s'ils ont tous les deux la valeur maximale.

>>> import operator
>>> stats = {'a':1000, 'b':3000, 'c': 100, 'd':3000}
>>> max(stats.iteritems(), key=operator.itemgetter(1))[0]
'b' 

si vous utilisez Python3:

>>> max(stats.items(), key=operator.itemgetter(1))[0]
'b'
418
répondu Priyanka Chaudhary 2018-02-22 17:51:35
max(stats, key=stats.get)
704
répondu A. Coady 2008-11-11 06:24:30

j'ai testé de nombreuses variantes, et c'est le moyen le plus rapide pour retourner la clé de dict avec la valeur max:

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))]

pour vous donner une idée, voici quelques méthodes candidates:

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) 

Le test du dictionnaire:

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}

et les résultats des tests sous 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%     --

et sous 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%     -- 

Vous pouvez voir que f1 est le plus rapide sous Python 3.2 et 2.7 (ou, plus complètement, keywithmaxval en haut de ce post)

169
répondu the wolf 2013-08-22 00:05:54

si vous avez besoin de connaître seulement une clé avec la valeur max, vous pouvez le faire sans iterkeys ou iteritems parce que l'itération à travers le dictionnaire en Python est l'itération à travers ses clés.

max_key = max(stats, key=lambda k: stats[k])

EDIT:

Dans les commentaires, @user1274878 :

je suis nouveau en python. Pouvez-vous expliquer votre réponse par étapes?

Oui...

max

max(itératif [,])

max (arg1, arg2, * args [, key])

renvoie le plus grand article dans un itérable ou le plus grand de deux arguments ou plus.

l'argument optionnel key décrit comment comparer des éléments pour obtenir un maximum parmi eux:

lambda <item>: return <a result of operation with item> 

les valeurs retournées seront comparer.

Dict

Python dict est une table de hachage. Une clé de dict est un hachage d'un objet déclaré comme une clé. En raison de raisons de performance itération bien qu'un dict mis en œuvre comme itération à travers ses clés.

donc nous pouvons l'utiliser pour supprimer l'opération d'obtention d'une liste de clés.

fermeture

Une fonction définie à l'intérieur d'une autre fonction est appelée une fonction imbriquée. Les fonctions imbriquées peuvent accéder aux variables du champ d'application.

la variable stats disponible par l'attribut __closure__ de la fonction lambda comme indicateur de la valeur de la variable définie dans le champ d'application parent.

46
répondu I159 2017-07-21 06:12:49

En voici un autre:

stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iterkeys(), key=lambda k: stats[k])

la fonction key renvoie simplement la valeur qui doit être utilisée pour le classement et max() renvoie immédiatement l'élément demandé.

35
répondu user994998 2014-01-26 22:09:04
key, value = max(stats.iteritems(), key=lambda x:x[1])

Si vous ne se soucient pas de la valeur (je serais surpris, mais) vous pouvez le faire:

key, _ = max(stats.iteritems(), key=lambda x:x[1])

j'aime le tuple déballage de mieux qu'un [0] indice à la fin de l'expression. Je n'aime pas beaucoup la lisibilité des expressions lambda, mais celle-ci est meilleure que l'opérateur.itemgetter (1) IMHO.

30
répondu Tim Ottinger 2015-09-30 18:39:59

étant donné que plus d'une entrée my ont la valeur max. Je ferais une liste des clés qui ont la valeur max comme leur valeur.

>>> 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']

Cela vous donnera " b " et toute autre touche max.

Note: pour python 3 utiliser stats.items() au lieu de stats.iteritems()

18
répondu Climbs_lika_Spyder 2018-08-07 18:16:33

pour obtenir la clé/valeur maximale du dictionnaire stats :

stats = {'a':1000, 'b':3000, 'c': 100}
  • Basé sur clés

>>> max(stats.items(), key = lambda x: x[0]) ('c', 100)

  • basé sur valeurs

>>> max(stats.items(), key = lambda x: x[1]) ('b', 3000)

bien sûr, si vous souhaitez obtenir uniquement la clé ou la valeur du résultat, vous pouvez utiliser un tuple indexer. Par exemple, pour obtenir la clé correspondant à la valeur maximale:

>>> max(stats.items(), key = lambda x: x[1])[0] 'b'

explication

Le dictionnaire de la méthode items() en Python 3 renvoie un visualiser les objets du dictionnaire. Lorsque cet objet de vue est itéré, par la fonction max , il donne les éléments du dictionnaire comme tuples de la forme (key, value) .

>>> list(stats.items()) [('c', 100), ('b', 3000), ('a', 1000)]

lorsque vous utilisez le lambda expression lambda x: x[1] , dans chaque itération, x est l'un de ces tuples (key, value) . Ainsi, en choisissant le bon indice, à vous de choisir si vous voulez comparer par touches ou par des valeurs.

Python 2

pour les versions Python 2.2+, le même code fonctionnera. Cependant, il est préférable de utilisez iteritems() méthode du dictionnaire au lieu de items() pour l'exécution.

Notes

11
répondu Karim Sonbol 2017-12-17 11:28:09

par les solutions itérées via les commentaires dans la réponse sélectionnée...

En Python 3:

max(stats.keys(), key=(lambda k: stats[k]))

En Python 2:

max(stats.iterkeys(), key=(lambda k: stats[k]))
9
répondu watsonic 2015-05-05 02:03:11

Avec collections.Counter vous pourriez le faire

>>> import collections
>>> stats = {'a':1000, 'b':3000, 'c': 100}
>>> stats = collections.Counter(stats)
>>> stats.most_common(1)
[('b', 3000)]

s'il y a lieu, vous pouvez simplement commencer par un collections.Counter vide et y ajouter

>>> stats = collections.Counter()
>>> stats['a'] += 1
:
etc. 
6
répondu ukrutt 2016-02-23 18:58:38

merci, très élégant, Je ne me souviens pas que max autorise un paramètre "clé".

BTW, pour obtenir la bonne réponse ("b"):

import operator
stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iteritems(), key=operator.itemgetter(1))[0]
4
répondu ricafeal 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')
4
répondu priya khokher 2018-05-04 06:50:19

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

2
répondu Jasha 2018-01-10 05:32:18

+1 à @Aric Coady est la solution la plus simple.

Et aussi une façon de choisir au hasard une des clés avec la valeur max dans le dictionnaire:

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])
1
répondu Woooody Amadeus 2018-01-02 08:57:23

exemple:

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

si vous voulez trouver la valeur max avec sa clé, peut-être follwing pourrait être simple, sans aucune fonction pertinente.

max(stats, key=stats.get)

la sortie est la clé qui a la valeur max.

1
répondu leo022 2018-08-23 04:08:56

je suis arrivé ici pour chercher comment retourner mydict.keys() basé sur la valeur de mydict.values() . Au lieu d'une seule clé retournée, je cherchais à retourner le nombre de valeurs x supérieur.

cette solution est plus simple que d'utiliser la fonction max() et vous pouvez facilement changer le nombre de valeurs retournées:

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

x = sorted(stats, key=(lambda key:stats[key]), reverse=True)
['b', 'a', 'c']

si vous voulez la clé de classement la plus élevée, il suffit d'utiliser l'indice:

x[0]
['b']

si vous voulez les deux plus hautes touches de classement, il suffit d'utiliser le tranchage de liste:

x[:2]
['b', 'a']
1
répondu ron g 2018-09-12 09:43:56
Counter = 0
for word in stats.keys():
    if stats[word]> counter:
        Counter = stats [word]
print Counter
0
répondu Erika Sawajiri 2015-12-26 12:31:42

j'ai testé la réponse acceptée et la solution la plus rapide de @thewolf sur une boucle très basique et la boucle était plus rapide que les deux:

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))

résultats:

Iterating: 3.8201940059661865
List creating: 6.928712844848633
Accepted answer: 5.464320182800293
0
répondu citizen2077 2017-07-11 16:26:24

Que Diriez-vous de:

 max(zip(stats.keys(), stats.values()), key=lambda t : t[1])[0]
0
répondu user3079275 2017-09-04 20:34:57