Получить ключ, соответствующий минимальному значению в словаре
Если у меня есть словарь Python, как я могу получить ключ к записи, которая содержит минимальное значение?
Я думал о чем-то с
15 ответов:
Best:
min(d, key=d.get)
-- нет причин возражать бесполезноlambda
косвенный слой или извлечение элементов или ключей!
вот ответ, который на самом деле дает решение ОП попросил:
>>> d = {320:1, 321:0, 322:3} >>> d.items() [(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)
используя
d.iteritems()
будет более эффективен для больших словарей.
для случая, когда у вас есть несколько минимальных ключей и вы хотите сохранить его простым
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, 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 """
Edit: это ответ на ОП оригинал вопрос о минимальном ключе, а не о минимальном ответе.
вы можете получить ключи диктатора с помощью и вы правы об использовании
min
чтобы найти минимум этого списка.
другой подход к решению проблемы нескольких ключей с одинаковым минимальным значением:
>>> 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]
использовать
min
С итератором (для python 3 Используйтеitems
вместоiteritems
); вместо лямбда используйтеitemgetter
от оператора, который быстрее, чем лямбда.from operator import itemgetter min_key, _ = min(d.iteritems(), key=itemgetter(1))
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]
для нескольких ключей, которые имеют равное наименьшее значение, вы можете использовать понимание списка:
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]
эквивалентная функциональная версия:
res = list(filter(lambda x: d[x]==minval, d))
Я сравнил, как работают следующие три варианта:
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 )
пример вывода:
#option 1 236230 0:00:14.136808 #option 2 236230 0:00:00.458026 #option 3 236230 0:00:00.824048
чтобы создать упорядочиваемый класс, вы должны переопределить 6 специальных функций, чтобы он вызывался функцией min ()
эти методы
__lt__ , __le__, __gt__, __ge__, __eq__ , __ne__
чтобы они были меньше, меньше или равны, больше, больше или равны, равны, не равны. например, вы должны реализовать__lt__
следующим образом:def __lt__(self, other): return self.comparable_value < other.comparable_value
затем вы можете использовать функцию min следующим образом:
minValue = min(yourList, key=(lambda k: yourList[k]))
это работает для меня.