Sample query:
I have a dictionary
: keys are strings, values are integers.
Example:
stats = {'a':1000, 'b':3000, 'c': 100}
I’d like to get 'b'
as an answer, since it’s the key with a higher value.
I did the following, using an intermediate list with reversed key-value tuples:
inverse = [(value, key) for key, value in stats.items()]
print max(inverse)[1]
Is that one the better (or even more elegant) approach?
How to get key with maximum value in Python dictionary?
You can use operator.itemgetter
for that:
import operator
stats = {'a':1000, 'b':3000, 'c': 100}
max(stats.iteritems(), key=operator.itemgetter(1))[0]
And instead of building a new list in memory use stats.iteritems()
. The key
parameter to the max()
function is a function that computes a key that is used to determine how to rank items.
Please note that if you were to have another key-value pair ‘d’: 3000 that this method will only return one of the two even though they both have the maximum value.
>>> import operator
>>> stats = {'a':1000, 'b':3000, 'c': 100, 'd':3000}
>>> max(stats.iteritems(), key=operator.itemgetter(1))[0]
'b'
If using Python3:
>>> max(stats.items(), key=operator.itemgetter(1))[0]
'b'
Answer #2:
Simplest answer would be:
max(stats, key=stats.get)
Answer #3:
I have tested MANY variants, and this is the fastest way to return the key of dict with the max value:
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))]
To give you an idea, here are some candidate methods:
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)
The test dictionary:
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}
And the test results under 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% --
And under 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% --
You can see that f1
is the fastest under Python 3.2 and 2.7 (or, more completely, keywithmaxval
at the top of this post)
Answer #4:
You can use:
max(d, key = d.get)
# which is equivalent to
max(d, key = lambda k : d.get(k))
To return the key, value pair use:
max(d.items(), key = lambda k : k[1])
Answer #5:
If you need to know only a key with the max value you can do it without iterkeys
or iteritems
because iteration through dictionary in Python is iteration through it’s keys.
max_key = max(stats, key=lambda k: stats[k])
max
max(iterable[, key])
max(arg1, arg2, *args[, key])
Return the largest item in an iterable or the largest of two or more arguments.
The optional key
argument describes how to compare elements to get maximum among them:
lambda <item>: return <a result of operation with item>
Returned values will be compared.
Dict
Python dict is a hash table. A key of dict is a hash of an object declared as a key. Due to performance reasons iteration though a dict implemented as iteration through it’s keys.
Therefore we can use it to rid operation of obtaining a keys list.
Closure
A function defined inside another function is called a nested function. Nested functions can access variables of the enclosing scope.
The stats
variable available through __closure__
attribute of the lambda
function as a pointer to the value of the variable defined in the parent scope.
How to get key with maximum value in dictionary in Python?
Example:
stats = {'a':1000, 'b':3000, 'c': 100}
if you wanna find the max value with its key, maybe follwing could be simple, without any relevant functions.
max(stats, key=stats.get)
the output is the key that has the max value.
Answer #7:
Given that more than one entry my have the max value. I would make a list of the keys that have the max value as their value.
>>> 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']
This will give you ‘b’ and any other max key as well.
Note: For python 3 use stats.items()
instead of stats.iteritems()
.
Answer #8:
To get the maximum key/value of the dictionary stats
:
stats = {'a':1000, 'b':3000, 'c': 100}
- Based on keys
>>> max(stats.items(), key = lambda x: x[0]) ('c', 100)
- Based on values
>>> max(stats.items(), key = lambda x: x[1]) ('b', 3000)
Of course, if you want to get only the key or value from the result, you can use tuple indexing. For Example, to get the key corresponding to the maximum value:
>>> max(stats.items(), key = lambda x: x[1])[0] 'b'
Explanation
The dictionary method items()
in Python 3 returns a view object of the dictionary. When this view object is iterated over, by the max
function, it yields the dictionary items as tuples of the form (key, value)
.
>>> list(stats.items()) [('c', 100), ('b', 3000), ('a', 1000)]
When you use the lambda
expression lambda x: x[1]
, in each iteration, x
is one of these tuples (key, value)
. So, by choosing the right index, you select whether you want to compare by keys or by values.
Python 2
For Python 2.2+ releases, the same code will work. However, it is better to use iteritems()
dictionary method instead of items()
for performance.
Hope you learned something from this post.
Follow Programming Articles for more!