2

You can get the key with max value in dictionary this way max(d, key=d.get). The question when two or more keys have the max how can you set a preferred key.

I found a way to do this by perpending the key with a number.

Is there a better way ?

In [56]: d = {'1a' : 5, '2b' : 1, '3c' : 5 }

In [57]: max(d, key=d.get)
Out[57]: '1a'

In [58]: d = {'4a' : 5, '2b' : 1, '3c' : 5 }

In [59]: max(d, key=d.get)
Out[59]: '3c'
sten
  • 7,028
  • 9
  • 41
  • 63
  • Have `key` (it accepts *a* function) return a value corresponding to a *valid* ordering, based on how 'max' is defined: the 'preferred max' is larger than 'all other would-be-duplicate max' values. It is unclear what makes some key 'preferred' here: maybe there is a lookup/weight table? – user2864740 Dec 06 '18 at 23:54

3 Answers3

3

The function given in the key argument can return a tuple. The second element of the tuple will be used if there are several maximums for the first element. With that, you can use the method you want, for example with two dictionnaries:

d = {'a' : 5, 'b' : 1, 'c' : 5 }
d_preference = {'a': 1, 'b': 2, 'c': 3}
max(d, key=lambda key: (d[key], d_preference[key]))
# >> 'c'

d_preference = {'a': 3, 'b': 2, 'c': 1}
max(d, key=lambda key: (d[key], d_preference[key]))
# >> 'a'
Axel Puig
  • 1,304
  • 9
  • 19
1

This is a similar idea to @AxelPuig's solution. But, instead of relying on an auxiliary dictionary each time you wish to retrieve an item with max or min value, you can perform a single sort and utilise collections.OrderedDict:

from collections import OrderedDict

d = {'a' : 5, 'b' : 1, 'c' : 5 }

d_preference1 = {'a': 1, 'b': 2, 'c': 3}
d_preference2 = {'a': 3, 'b': 2, 'c': 1}

d1 = OrderedDict(sorted(d.items(), key=lambda x: -d_preference1[x[0]]))
d2 = OrderedDict(sorted(d.items(), key=lambda x: -d_preference2[x[0]]))

max(d1, key=d.get)  # c
max(d2, key=d.get)  # a

Since OrderedDict is a subclass of dict, there's generally no need to convert to a regular dict. If you are using Python 3.7+, you can use the regular dict constructor, since dictionaries are insertion ordered.

As noted on the docs for max:

If multiple items are maximal, the function returns the first one encountered.

jpp
  • 159,742
  • 34
  • 281
  • 339
0

A slight variation on @AxelPuig's answer. You fix an order of keys in a priorities list and take the max with key=d.get.

d = {"1a": 5, "2b": 1, "3c": 5}
priorities = list(d.keys())

print(max(priorities, key=d.get))
hilberts_drinking_problem
  • 11,322
  • 3
  • 22
  • 51