tjvr
tjvr

Reputation: 17951

Get the key corresponding to the minimum value within a dictionary

If I have a Python dictionary, how do I get the key to the entry which contains the minimum value?

I was thinking about something to do with the min() function...

Given the input:

{320:1, 321:0, 322:3}

It would return 321.

Upvotes: 476

Views: 484679

Answers (17)

Mark Rushakoff
Mark Rushakoff

Reputation: 258188

This returns the key, value pair tuple after comparing values:

>>> d = {320:1, 321:0, 322:3}
>>> d.items()
dict_items([(320, 1), (321, 0), (322, 3)])  # Python 2.7 [(320, 1), (321, 0), (322, 3)]
>>> # find the minimum by comparing the second element of each tuple
>>> min(d.items(), key=lambda x: x[1]) 
(321, 0)

For Python 2.7, use d.iteritems() for larger dictionaries as it avoid copying. Python 3's dict.items() is already an itemview so no changes need.

Upvotes: 81

Sefa_Kurtuldu
Sefa_Kurtuldu

Reputation: 24

my_dic = {320:1, 321:0, 322:3}
min_value = sorted(my_dic, key=lambda k: my_dic[k])[0]
print(min_value)

A solution with only the sorted method.

  1. I sorted values from smallest to largest with sorted method
  2. When we get the first index, it gives the smallest key.

Upvotes: 0

turtle_in_mind
turtle_in_mind

Reputation: 1152

min(zip(d.values(), d.keys()))[1]

Use the zip function to create an iterator of tuples containing values and keys. Then wrap it with a min function which takes the minimum based on the first key. This returns a tuple containing (value, key) pair. The index of [1] is used to get the corresponding key.

Upvotes: 7

Muhammad Korra
Muhammad Korra

Reputation: 1

To create an orderable class you have to override six special functions, so that it would be called by the min() function.

These methods are__lt__ , __le__, __gt__, __ge__, __eq__ , __ne__ in order they are less than, less than or equal, greater than, greater than or equal, equal, not equal.

For example, you should implement __lt__ as follows:

def __lt__(self, other):
  return self.comparable_value < other.comparable_value

Then you can use the min function as follows:

minValue = min(yourList, key=(lambda k: yourList[k]))

This worked for me.

Upvotes: 2

perimosocordiae
perimosocordiae

Reputation: 17797

You can get the keys of the dict using the keys function, and you're right about using min to find the minimum of that list.

This is an answer to the OP's original question about the minimal key, not the minimal answer.

Upvotes: 4

U13-Forward
U13-Forward

Reputation: 71580

Or __getitem__:

>>> d = {320: 1, 321: 0, 322: 3}
>>> min(d, key=d.__getitem__)
321

Upvotes: 3

Alex Martelli
Alex Martelli

Reputation: 881635

Best: min(d, key=d.get) -- no reason to interpose a useless lambda indirection layer or extract items or keys!

>>> d = {320: 1, 321: 0, 322: 3}
>>> min(d, key=d.get)
321

Upvotes: 967

jpp
jpp

Reputation: 164673

For multiple keys which have equal lowest value, you can use a list comprehension:

d = {320:1, 321:0, 322:3, 323:0}

minval = min(d.values())
res = [k for k, v in d.items() if v==minval]

[321, 323]

An equivalent functional version:

res = list(filter(lambda x: d[x]==minval, d))

Upvotes: 57

svinec
svinec

Reputation: 777

I compared how the following three options perform:

    import random, datetime

myDict = {}
for i in range( 10000000 ):
    myDict[ i ] = random.randint( 0, 10000000 )



# OPTION 1

start = datetime.datetime.now()

sorted = []
for i in myDict:
    sorted.append( ( i, myDict[ i ] ) )
sorted.sort( key = lambda x: x[1] )
print( sorted[0][0] )

end = datetime.datetime.now()
print( end - start )



# OPTION 2

start = datetime.datetime.now()

myDict_values = list( myDict.values() )
myDict_keys = list( myDict.keys() )
min_value = min( myDict_values )
print( myDict_keys[ myDict_values.index( min_value ) ] )

end = datetime.datetime.now()
print( end - start )



# OPTION 3

start = datetime.datetime.now()

print( min( myDict, key=myDict.get ) )

end = datetime.datetime.now()
print( end - start )

Sample output:

#option 1
236230
0:00:14.136808

#option 2
236230
0:00:00.458026

#option 3
236230
0:00:00.824048

Upvotes: 2

aditya royal matturi
aditya royal matturi

Reputation: 111

d={}
d[320]=1
d[321]=0
d[322]=3
value = min(d.values())
for k in d.keys(): 
    if d[k] == value:
        print k,d[k]

Upvotes: 2

netskink
netskink

Reputation: 4539

For the case where you have multiple minimal keys and want to keep it simple

def minimums(some_dict):
    positions = [] # output variable
    min_value = float("inf")
    for k, v in some_dict.items():
        if v == min_value:
            positions.append(k)
        if v < min_value:
            min_value = v
            positions = [] # output variable
            positions.append(k)

    return positions

minimums({'a':1, 'b':2, 'c':-1, 'd':0, 'e':-1})

['e', 'c']

Upvotes: 8

Use min with an iterator (for python 3 use items instead of iteritems); instead of lambda use the itemgetter from operator, which is faster than lambda.

from operator import itemgetter
min_key, _ = min(d.iteritems(), key=itemgetter(1))

Upvotes: 2

PaulMcG
PaulMcG

Reputation: 63709

Another approach to addressing the issue of multiple keys with the same min value:

>>> dd = {320:1, 321:0, 322:3, 323:0}
>>>
>>> from itertools import groupby
>>> from operator import itemgetter
>>>
>>> print [v for k,v in groupby(sorted((v,k) for k,v in dd.iteritems()), key=itemgetter(0)).next()[1]]
[321, 323]

Upvotes: 4

Tony Veijalainen
Tony Veijalainen

Reputation: 5555

If you are not sure that you have not multiple minimum values, I would suggest:

d = {320:1, 321:0, 322:3, 323:0}
print ', '.join(str(key) for min_value in (min(d.values()),) for key in d if d[key]==min_value)

"""Output:
321, 323
"""

Upvotes: 4

Daniel Stutzbach
Daniel Stutzbach

Reputation: 76667

>>> d = {320:1, 321:0, 322:3}
>>> min(d, key=lambda k: d[k]) 
321

Upvotes: 8

eruciform
eruciform

Reputation: 7736

# python 
d={320:1, 321:0, 322:3}
reduce(lambda x,y: x if d[x]<=d[y] else y, d.iterkeys())
  321

Upvotes: -1

abyx
abyx

Reputation: 72808

min(d.items(), key=lambda x: x[1])[0]

Upvotes: 14

Related Questions