获取与字典中的最小值对应的键


304

如果我有Python字典,如何获得包含最小值的条目的键?

我正在考虑与该min()功能有关的事情...

给定输入:

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

它将返回321


您所说的回报中有错字吗?否则,为什么是321?不应该是320吗?
GreenMatt 2010年

3
@myself:好的,现在我知道了-所需的是条目的键,其中条目的值最小。请更好地措辞这个问题,因为其他人显然和我一样。
GreenMatt 2010年

2
数据结构意识日:如果仅查询(或删除)最小元素,请考虑使用优先级队列或堆。
Panic Panic

Answers:


596

最好:min(d, key=d.get)-没有理由插入无用的lambda间接层或提取项目或密钥!


5
@KarelBílek表示您将“”列表[11, 22, 33]而不是“字典”作为“ d”传递{1: 11, 2:22, 3:33}。“ d.get”对字典有效,但对列表无效。
ToolmakerSteve

9
如果两个不同的键具有相同的值怎么办?它们恰好都是最小值?您如何才能使它们都返回?
user3226932 '16

5
如果dict值是列表(例如ex d={"a":[10, None], "b":[20, None]},其中从d [key] [0]计算出最小值)可以使用这种技术吗?
TrakJohnson,2016年

4
这是如何运作的?那是什么类型的min函数,我认为min()仅将单个值或列表作为参数。如何遍历字典中的所有条目?
Azureai

2
min()返回排序后的第一个值中的值。键指定对值进行排序的方式。key=d.get表示列表将按字典的值排序。
notilas18年

45

这实际上是提供OP所需解决方案的答案:

>>> 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()但是,对于较大的词典,使用将更为有效。


3
您可以使用代替lambda operator.itemgetter(1)
菲利普

2
而是lamda使用d.get
Texom512

这不会返回要求的键,而是(键,值)对。
Eric O Lebigot

14

对于具有相等最小值的多个键,可以使用列表理解:

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))

1
您的答案非常有用,其他人可能也同意:请在已接受的答案中看到有关此问题的多条评论。但是,我需要回来两次才能找到它:您是否考虑对接受的答案提出建议?您的实际上是互补的。
jmon12



6

对于您有多个最小键并希望保持简单的情况

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']

4

如果您不确定是否没有多个最小值,我建议:

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
"""

3

编辑:这是OP 关于最小密钥而不是最小答案的原始问题的答案。


您可以使用keys函数获取字典的键,并且正确使用min来查找该列表的最小值。


真正不值得一票的是,因为海报的原始问题并不像以前那样清晰。
GreenMatt 2010年

@ Space_C0wb0y:也许您会很友善地注意到,在我回答之后,OP编辑了他的问题以表示不同的意思
Eli Bendersky 2010年

3

解决具有相同最小值的多个键的另一种方法:

>>> 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]

2

使用min与迭代器(对于Python 3使用items代替iteritems); 代替lambda使用itemgetterfrom运算符,它比lambda更快。

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


1

我比较了以下三个选项的执行情况:

    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

0

要创建可排序的类,您必须重写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]))

这对我有用。


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

使用zip函数创建包含值和键的元组的迭代器。然后用min函数包装它,min函数根据第一个键取最小值。这将返回一个包含(值,键)对的元组。索引[1]用于获取对应的密钥


2
尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以提高其长期价值。
β.εηοιτ.βε

@β.εηοιτ.βε更好吗?
rajn

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

6
1)Reduce通常比itertools慢。2)大多数的reduce实施都可以用任何或全部方法来简化。3)我是GvR的巨大喉舌。4)操作员模块不需要最简单的lambda,因此无论如何应将复杂的lambda定义为实函数。也许我只是害怕函数式编程。;)
MikeD 2010年

@miked:告诉我更多。什么是gvr,什么是操作员模块?你可以发布链接吗?我可能认识其他人,但我仍然只是python的中间人。愿意学习!:-)
eruciform

GvR是Python仁慈的独裁者Guido van Rossum。这是他的五年老帖子,解释了为什么Lisp-isms(map,filter,reduce,lambda)在python中没有太大的位置,而这些原因在今天仍然是正确的。操作员模块具有提取成员的替代项:与“ itemgetter(1)”相比,“ lambda x:x [1]”是一个更长的字符,并且可以说花了更长的时间才能理解。我的空间不足,但要提问!
MikeD 2010年


实际上,他们不需要重新实现内置的(min())。
Eric O Lebigot

-8

这是你想要的?

d = dict()
d[15.0]='fifteen'
d[14.0]='fourteen'
d[14.5]='fourteenandhalf'

print d[min(d.keys())]

打印“十四”


8
-1:不是问题所问。您要使用最小键返回值,OP希望键使用最小键
Brian S
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.