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
.
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
.
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
min(d.keys(), key=d.get)
to clarify this returns one of the keys to the reader; but in 2.x .keys()
is wasteful (and .iterkeys()
just muddies the picture). What do you think? –
Chaim AttributeError: 'list' object has no attribute 'get'
- what does that mean, dammit? –
Sketchy [11, 22, 33]
, instead of a dictionary e.g. {1: 11, 2:22, 3:33}
. 'd.get' is valid for a dictionary, but not for a list. –
Loach d={"a":[10, None], "b":[20, None]}
, where the min is calculated from d[key][0] ? –
Foreigner min()
return the value in the first value in sorted. key designate the way to sort the values. key=d.get
means the list will be sorted by values of the dictionary. –
Mcsweeney get
member function). For a more generic version, the lambda indirection would actually be necessary. –
Citronellal d.get
you'll lose the typing information from d
. In more recent mypy (e.g. >0.9.3.1), you'll get a type error. To preserve typing information, use d.__getitem__
–
Sinuate 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.
operator.itemgetter(1)
. –
Kant dict.iteritems
became dict.items
. –
Boondoggle d.get
won't work with d.items()
, it'll work with just d
; won't help when you want the key-value pair result. –
Trustworthy 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))
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']
>>> d = {320:1, 321:0, 322:3}
>>> min(d, key=lambda k: d[k])
321
key=d.get
is better. –
Janae 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.
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]
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
"""
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.
Or __getitem__
:
>>> d = {320: 1, 321: 0, 322: 3}
>>> min(d, key=d.__getitem__)
321
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.
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
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]
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))
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.
# python
d={320:1, 321:0, 322:3}
reduce(lambda x,y: x if d[x]<=d[y] else y, d.iterkeys())
321
min()
). –
Janae © 2022 - 2024 — McMap. All rights reserved.
O(n)
time to read the list? – Matrass