1

Say I have the following code that makes a dict:

x = 0
myHash = {}
name = ["Max","Fred","Alice","Bobby"]

while x <= 3:
    myHash[name[x]] = x
    x += 1

l = sorted(myHash.values(), reverse=True)
largestNum = l[0]

# print myHash.getKeyFromValue(largestNum)

Is it possible to easily get the key that is paired to my largestNum variable without looping through the entire dict? Something like the pseudo code in the line at the bottom.

Note: I don't want to get a value from a key. I want the reverse of that.

Remi Guan
  • 21,506
  • 17
  • 64
  • 87
Sam
  • 2,172
  • 3
  • 24
  • 43
  • 1
    Another way to get `myHash` dict: `{i: j for j, i in enumerate(name)}` – Remi Guan Nov 04 '15 at 05:08
  • To make your question more clear: are you interested in specifically finding the key from the largest value? Or are you interested in generally finding a key from an arbitrary value? – Robᵩ Nov 04 '15 at 05:09
  • Getting the key from the largest value solves my current problem. But it would be nice to know a general way to find a key from an arbitrary value. – Sam Nov 04 '15 at 05:11
  • @Sam: Unless the values are unique, you have no means of identifying a unique key which corresponded to the value found. – ShadowRanger Nov 04 '15 at 05:12
  • An idea from question [get key by value in dictionary](https://stackoverflow.com/questions/8023306/get-key-by-value-in-dictionary): `largest_value = max(myHash.values()); [name for name, index in myHash.items() if index == largest_value]`. – Remi Guan Nov 04 '15 at 05:13
  • @ShadowRanger Yes, that's true. In this particular case I can guarantee that my values are unique. But I understand that this means a more general solution may not be possible. – Sam Nov 04 '15 at 05:14
  • @Sam: I gave the basic setup below. Still requires the values to be hashable (otherwise they're not legal keys), but it maintains `O(1)` expected lookup costs. – ShadowRanger Nov 04 '15 at 05:17
  • @ShadowRanger Thanks. It is a great solution for my specific problem. I'll accept it as the answer when StackOverflow lets me. – Sam Nov 04 '15 at 05:18

1 Answers1

1

Don't just sort the values. Sort the items by their values, and get the key for free.

from operator import itemgetter

l = sorted(myHash.items(), key=itemgetter(1), reverse=True)
largestKey, largestNum = l[0]

Note: If you only want the largest value, not the rest of the sort results, you can save some work and skip the full sorted work (reducing work from O(n log n) to O(n)):

largestKey, largestNum = max(myHash.items(), key=itemgetter(1))

For the general case of inverting a dict, if the values are unique, it's trivial to create a reversed mapping:

invert_dict = {v: k for k, v in orig_dict.items()}

If the values aren't unique, and you want to find all keys corresponding to a single value with a single lookup, you'd invert to a multi-dict:

from collections import defaultdict

invert_dict = defaultdict(set)
for k, v in orig_dict.items():
    invert_dict[v].add(k)
# Optionally convert back to regular dict to avoid lookup auto-vivification in the future:
# invert_dict = dict(invert_dict)
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Side-note: If you're in Python 2.7, use `viewitems` and `viewvalues` instead of `items` and `values` to avoid making intermediate `list`s. It also means the `2to3` converter will convert the usage directly (because `viewitems` and `viewvalues` are directly equivalent to the Py3 version of `items` and `values`). Same goes for `keys`/`viewkeys`, but usually, if you're just iterating `dict` keys, iterate directly, no method call at all. – ShadowRanger Nov 04 '15 at 05:11
  • If you don't have duplicate value in dictionary's value then you can use this approach; ....... .....#find max value from your values of dictionary .....dictValue = {"a":1,"b":2,"c":3}ValuesList = dictValue.values() .....KeyList = dictValue.keys() .....MaxValue = max(ValuesList) .....YourReqKey = KeyList[ValuesList.index(MaxValue)] – Raj Damani Jun 20 '16 at 06:34