stats = {'a':1000, 'b':3000, 'c': 100, 'd':3000}
import random
maxV = max(stats.values())
# Choice is one of the keys with max value
choice = random.choice([key for key, value in stats.items() if value == maxV])
8
我测试了很多变种,这是以最大值返回dict键的最快方法:
def keywithmaxval(d):
""" a) create a list of the dict's keys and values;
b) return the key with the max value"""
v=list(d.values())
k=list(d.keys())
return k[v.index(max(v))]
为了给你一个想法,这里有一些候选方法:
def f1():
v=list(d1.values())
k=list(d1.keys())
return k[v.index(max(v))]
def f2():
d3={v:k for k,v in d1.items()}
return d3[max(d3)]
def f3():
return list(filter(lambda t: t[1]==max(d1.values()), d1.items()))[0][0]
def f3b():
# same as f3 but remove the call to max from the lambda
m=max(d1.values())
return list(filter(lambda t: t[1]==m, d1.items()))[0][0]
def f4():
return [k for k,v in d1.items() if v==max(d1.values())][0]
def f4b():
# same as f4 but remove the max from the comprehension
m=max(d1.values())
return [k for k,v in d1.items() if v==m][0]
def f5():
return max(d1.items(), key=operator.itemgetter(1))[0]
def f6():
return max(d1,key=d1.get)
def f7():
""" a) create a list of the dict's keys and values;
b) return the key with the max value"""
v=list(d1.values())
return list(d1.keys())[v.index(max(v))]
def f8():
return max(d1, key=lambda k: d1[k])
tl=[f1,f2, f3b, f4b, f5, f6, f7, f8, f4,f3]
cmpthese.cmpthese(tl,c=100)
>>> stats = collections.Counter()
>>> stats['a'] += 1
:
etc.
0
Counter = 0
for word in stats.keys():
if stats[word]> counter:
Counter = stats [word]
print Counter
36
我测试了接受的答案和@thewolf对一个非常基本的循环的最快解决方案,并且循环比两者都快:
import time
import operator
d = {"a"+str(i): i for i in range(1000000)}
def t1(dct):
mx = float("-inf")
key = None
for k,v in dct.items():
if v > mx:
mx = v
key = k
return key
def t2(dct):
v=list(dct.values())
k=list(dct.keys())
return k[v.index(max(v))]
def t3(dct):
return max(dct.items(),key=operator.itemgetter(1))[0]
start = time.time()
for i in range(25):
m = t1(d)
end = time.time()
print ("Iterating: "+str(end-start))
start = time.time()
for i in range(25):
m = t2(d)
end = time.time()
print ("List creating: "+str(end-start))
start = time.time()
for i in range(25):
m = t3(d)
end = time.time()
print ("Accepted answer: "+str(end-start))
结果:
Iterating: 3.8201940059661865
List creating: 6.928712844848633
Accepted answer: 5.464320182800293
20 回答
堆队列是一个 generalised 解决方案,它允许您提取按值排序的前n个键:
注意
dict.__getitem__
是句法糖dict[]
调用的方法 . 与dict.get
相反,如果找不到密钥,它将返回KeyError
,这在此处不会发生 .谢谢,非常优雅,我不记得max允许“关键”参数 .
顺便说一句,要获得正确答案('b'),必须:
根据所选答案中的注释,通过迭代解决方案...
在Python 3中:
在Python 2中:
这是另一个:
函数
key
只返回应该用于排名的值,max()
立即返回所需元素 .max((value, key) for key, value in stats.items())[1]
我来到这里寻找如何根据
mydict.values()
的值返回mydict.keys()
. 而不是只返回一个键,我希望返回前面的x个值 .此解决方案比使用
max()
函数更简单,您可以轻松更改返回的值的数量:如果您想要单个最高排名的密钥,只需使用索引:
如果您想要排名前两位的最高排名键,只需使用列表切片:
要获取字典
stats
的最大键/值:>>> max(stats.items(), key = lambda x: x[0]) ('c', 100)
>>> max(stats.items(), key = lambda x: x[1]) ('b', 3000)
当然,如果您只想从结果中获取键或值,则可以使用元组索引 . 例如,要获取与最大值对应的键:
>>> max(stats.items(), key = lambda x: x[1])[0] 'b'
Explanation
Python 3中的字典方法items()返回字典的view object . 当通过
max
函数迭代此视图对象时,它会将字典项生成为(key, value)
形式的元组 .>>> list(stats.items()) [('c', 100), ('b', 3000), ('a', 1000)]
当您使用lambda表达式
lambda x: x[1]
时,在每次迭代中,x
是这些元组之一(key, value)
. 因此,通过选择正确的索引,您可以选择是按键还是按值进行比较 .Python 2
对于Python 2.2版本,相同的代码将起作用 . 但是,最好使用iteritems()字典方法而不是items()来提高性能 .
Notes
此答案基于Climbs_lika_Spyder's answer的评论 .
使用过的代码在Python 3.5.2和Python 2.7.10上进行了测试 .
例:
如果你想用它的键找到最大值,也许后续可能很简单,没有任何相关的功能 .
输出是具有最大值的键 .
怎么样:
如果您只需要知道具有最大值的键,则可以在没有
iterkeys
或iteritems
的情况下执行此操作,因为Python中的字典迭代是通过它的键进行迭代 .EDIT:
来自评论,@ user1274878:
是的...
最大
可选的
key
参数描述了如何比较元素以获得最大值:返回值将进行比较 .
Dict
Python dict是一个哈希表 . dict的一个关键是声明为键的对象的哈希 . 由于性能原因迭代虽然dict实现为迭代通过它的键 .
因此我们可以用它来摆脱获取密钥列表的操作 .
关闭
stats
变量可通过lambda
函数的__closure__
属性作为指向父作用域中定义的变量值的指针 .1到@Aric Coady最简单的解决方案 .
还有一种方法可以在字典中随机选择一个具有最大值的键:
我测试了很多变种,这是以最大值返回dict键的最快方法:
为了给你一个想法,这里有一些候选方法:
测试词典:
而Python 3.2下的测试结果:
在Python 2.7下:
您可以看到
f1
在Python 3.2和2.7下是最快的(或者更完整地,keywithmaxval
在本文的顶部)鉴于有多个条目,我有最大值 . 我会列出具有最大值作为其值的键 .
这将给你'b'和任何其他最大键 .
注意:对于python 3,使用
stats.items()
而不是stats.iteritems()
如果你不在乎关于 Value (我会感到惊讶,但是)你可以这样做:
我喜欢元组解包比表达式末尾的[0]下标更好 . 我从不喜欢lambda表达式的可读性,但是发现这个比operator.itemgetter(1)更好 .
您可以使用
operator.itemgetter
:而不是在内存中 Build 一个新的列表使用
stats.iteritems()
.max()
函数的key
参数是一个计算用于确定如何对项目进行排名的键的函数 .请注意,如果您要使用另一个键值对'd':3000,则此方法仅返回 two 的 one ,即使它们都具有最大值 .
如果使用Python3:
有
collections.Counter
你可以做到如果合适,您可以简单地从空
collections.Counter
开始并添加到它我测试了接受的答案和@thewolf对一个非常基本的循环的最快解决方案,并且循环比两者都快:
结果: