Python 在非零值字典中查找最大键的有效方法

Python 在非零值字典中查找最大键的有效方法,python,dictionary,Python,Dictionary,我是新的Python,并试图以更具Python风格和效率的方式实现代码。 给定一个包含数字键和值的字典,找到非零值的最大键的最佳方法是什么 谢谢像这样的事情应该很快就会发生: >>> x = {0: 5, 1: 7, 2: 0} >>> max(k for k, v in x.iteritems() if v != 0) 1 (删除!=0会稍微快一点,但会模糊其含义。)Python的max函数为“measure”函数使用键=参数 data = {1: 25,

我是新的Python,并试图以更具Python风格和效率的方式实现代码。 给定一个包含数字键和值的字典,找到非零值的最大键的最佳方法是什么


谢谢

像这样的事情应该很快就会发生:

>>> x = {0: 5, 1: 7, 2: 0}
>>> max(k for k, v in x.iteritems() if v != 0)
1

(删除
!=0
会稍微快一点,但会模糊其含义。)

Python的max函数为“measure”函数使用
键=
参数

data = {1: 25, 0: 75}
def keymeasure(key):
    return data[key] and key

print max(data, key=keymeasure)
使用内联lambda实现相同的效果和相同的局部变量绑定:

print max(data, key=(lambda k: data[k] and k))
将本地变量绑定到匿名密钥函数的最后一个备选方案

print max(data, key=(lambda k, mapping=data: mapping[k] and k))

要获得最大的钥匙,您可以使用该功能并按如下方式检查钥匙:

max(x.iterkeys())
要筛选出值为0的值,可以使用:

您可以将这些参数组合起来以获得所需的参数(因为
max
只接受一个参数,因此可以删除生成器表达式周围的括号):


如果我是你,速度是一个大问题,我可能会创建一个新的容器类“DictMax”,通过拥有一个内部索引堆栈来跟踪它最大的非零值元素,其中堆栈的顶部元素始终是字典中最大元素的键。这样,您每次都可以在恒定时间内获得最大的元素。

该函数取决于对全局变量的访问。坏主意。不,不是。这只取决于对同一范围的访问。所有这些都可以在一个函数作用域内,它仍然可以工作。@dalke,关键是函数应该将字典作为参数,而不是硬编码dict的名称。@steveha:不使用此解决方案还有其他原因。首先,它不处理{0:0,-1:-1},因为它实际上不忽略零值。但是说它“取决于对全局的访问”并不是其中之一。因为OP是新的,所以对正在发生的事情的描述可能也会有所帮助。请注意,在Python 3.x中,
。iterms
不再存在,并且
。items
返回一个迭代器。(与Python2.x不同,
.items
返回列表,
.iteritems
返回迭代器。)这里发生了什么?我们正在调用max()以查找最大的键。我们传递给max()的是一个“生成器表达式”,非常类似于“列表理解”。max()将重复获取k的值,并选择最大值。当v值不为零时,生成器表达式将仅返回k值。k和v值来自x.iteritems(),它返回键和值对。这段代码将在Python2.4及更新版本中运行,但正如Stephan202所指出的,对于Python3.x,您需要将“iteritems”替换为“items”。生成器表达式(和迭代器)的好处在于,它们一次给出一个值,而不是构建一些随后将立即销毁的大型列表对象。构建一个键、值元组列表,然后从中计算max(),这同样正确,但有点浪费。也许您应该使用更合适的数据结构(如堆)来检索集合中的最小/最大值。“更Pythonic”比什么?你目前的解决方案是什么?你不喜欢它什么地方?快到了!最后,移除方括号,剩下的是最佳解决方案。方括号构成一个列表理解,它构建整个列表,然后将整个列表传递给max()。不使用方括号,您将得到一个生成器表达式,它一次将一个值传递给max()。对于一小部分条目来说,这没什么大不了的,但是对于非常大的字典来说,建立一个列表然后销毁它的额外努力可能是相当大的。我刚刚更新了我的答案。。。从列表切换到生成器/迭代器仅供参考,您不需要额外的参数。max()的参数可以执行双重任务:它们可以是max()函数调用的参数,也可以是生成器表达式周围的参数。试试看!:-)
(k for k, v in x.iteritems() if v != 0)
max(k for k, v in x.iteritems() if v != 0)