Question Obtenir la clé avec une 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 obtenir 'b' en guise de 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 valeur-clé inversés:

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

Est-ce que c'est une meilleure approche (ou même plus élégante)?


541
2017-11-06 10:49


origine


Réponses:


Vous pouvez utiliser operator.itemgetter pour ça:

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 utilisation de la mémoire stats.iteritems(). le key paramètre à la max() function est une fonction qui calcule une clé utilisée pour déterminer comment classer les éléments.

S'il vous plaît noter que si vous deviez avoir une autre paire valeur-clé 'd': 3000 que cette méthode ne retournera un du deux même si tous les deux ont 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'

404
2017-11-06 10:58



max(stats, key=stats.get)

665
2017-11-11 06:24



J'ai testé BEAUCOUP de 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 dictionnaire de test:

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 du test 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%     -- 

Tu peux voir ça f1 est le plus rapide sous Python 3.2 et 2.7 (ou, plus complètement, keywithmaxval en haut de ce post)


164
2017-09-09 23:30



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

MODIFIER:

De commentaires, @ user1274878:

Je suis nouveau à python. Pouvez-vous s'il vous plaît expliquer votre réponse par étapes?

Oui...

max

max (itérable [, clé])

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

Renvoie le plus grand élément dans un itérable ou le plus grand de deux ou plusieurs arguments.

L'option key argument décrit comment comparer les éléments pour obtenir le maximum entre eux:

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

Les valeurs renvoyées seront comparées.

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 l'itération des raisons de performance, un dict est implémenté comme une itération à travers ses touches.

Par conséquent, nous pouvons l'utiliser pour débarrasser l'opération d'obtenir 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 de la portée englobante.

le stats variable disponible via __closure__ attribut de la lambda fonctionne comme un pointeur sur la valeur de la variable définie dans la portée parent.


45
2018-02-07 17:31



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 devrait être utilisée pour le classement et max() renvoie l'élément demandé immédiatement.


34
2017-11-06 11:28



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

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

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

Je préfère que le tuple déballe mieux qu'un indice [0] à la fin de l'expression. Je n'aime pas beaucoup la lisibilité des expressions lambda, mais je trouve celle-ci meilleure que l'operator.itemgetter (1) IMHO.


30
2017-11-07 14:41



Étant donné que plus d'une entrée a la valeur maximale. Je voudrais faire une liste des clés qui ont la valeur max comme valeur.

>>> stats = {'a':1000, 'b':3000, 'c': 100, 'd':3000}
>>> [key for key,val in stats.iteritems() if val == max(stats.values())]
['b', 'd']

Cela vous donnera 'b' et toute autre touche max aussi.


17
2018-05-02 13:07



Par les solutions itérées par des 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
2018-05-05 02:03



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 voulez obtenir seulement la clé ou la valeur du résultat, vous pouvez utiliser l'indexation de tuple. Par exemple, pour obtenir la clé correspondant à la valeur maximale:

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

Explication

La méthode du dictionnaire items() en Python 3 renvoie un voir l'objet du dictionnaire. Lorsque cet objet de vue est itéré, par le max fonction, il donne les éléments du dictionnaire sous forme de 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], à chaque itération, x  est l'un de ces tuples (key, value). Ainsi, en choisissant le bon index, vous choisissez si vous voulez comparer par des clés ou par des valeurs.

Python 2

Pour les versions Python 2.2+, le même code fonctionnera. Cependant, il vaut mieux utiliser iteritems() méthode de dictionnaire au lieu de items() pour la performance.

Remarques


9
2017-12-17 11:28



Avec collections.Counter vous pourriez faire

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

Le cas échéant, vous pouvez simplement commencer par un vide collections.Counter et ajoutez-y

>>> stats = collections.Counter()
>>> stats['a'] += 1
:
etc. 

6
2018-02-23 18:58



Merci, très élégant, je ne me souviens pas que max permet un paramètre "clé".

BTW, pour obtenir la bonne réponse («b»), il doit être:

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

4
2017-11-06 11:04