2009-10-12 59 views
6

我是新的Python,并试图以更加Pythonic和高效的方式实现代码。 给定一个包含数字键和值的字典,找到非零值的最大键的最佳方法是什么?找到非零值字典中最大关键字的有效方法

感谢

+0

也许您应该使用更合适的数据结构(例如堆)来检索集合中的最小值/最大值。 – Juliet 2009-10-12 18:17:09

+1

“更多Pythonic”比什么?你目前的解决方案是什么?你不喜欢它什么? – 2009-10-13 00:38:26

回答

12

像这样的东西应该是相当快的:

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

(去除!= 0会稍微快一些还在,但有点模糊的意思)

+2

由于OP是新的,对发生的事情的描述也可能会有所帮助。 – 2009-10-12 18:03:06

+6

请注意,在Python 3.x中'.iteritems'不再存在,'.items'返回一个迭代器。 (与Python 2.x不同,'.items'返回一个列表,'.iteritems'返回一个迭代器。) – Stephan202 2009-10-12 18:22:30

+3

这里发生了什么?我们调用max()来查找最大的键。我们传递给max()的是“生成器表达式”,与“列表理解”非常相似。 max()会重复获得k的值,并且它会选择最大值。当v值不为零时,生成器表达式将只返回k个值。 k和v值来自x.iteritems(),它返回键值对。这段代码可以在Python 2.4或更新的版本中工作,但正如Stephan202指出的那样,对于Python 3.x,您需要用“items”替换“iteritems”。 – steveha 2009-10-12 18:46:29

1

Python的最大功能需要“度量”函数的参数key=

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

print max(data, key=keymeasure) 

使用内嵌拉姆达达到同样的效果,并同时结合局部变量:

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

最后的选择在局部变量绑定到匿名键功能

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

该功能取决于对全局的访问。馊主意。 – 2009-10-12 18:00:55

+1

不,它不。这只取决于有权访问相同的范围。所有这些都可以在函数范围内,它仍然可以工作。 – 2009-10-12 18:28:11

+2

@dalke,关键在于函数应该将字典作为参数,而不是对字典的名称进行硬编码。 – steveha 2009-10-12 18:42:11

10

要得到最大的钥匙,你可以使用max功能并检查这样的钥匙:

max(x.iterkeys()) 

要过滤掉那些其中值是0,你可以使用一个generator expression

(k for k, v in x.iteritems() if v != 0) 

您可以结合这些让你在找什么(因为max只有一个参数,周围的括号发电机表达式可以删除):

max(k for k, v in x.iteritems() if v != 0) 
+2

几乎在那里!最后,你删除方括号,你留下了最好的解决方案。方括号创建一个列表理解,它构建了整个列表,然后整个列表被传递给max()。离开方括号,你会得到一个生成器表达式,它一次将值传递给max()。对于少数项目来说没什么大不了的,但对于非常大的字典来说,构建列表然后销毁它的额外工作可能是相当大的。 – steveha 2009-10-12 18:20:03

+0

我刚更新了我的答案...从列表切换到生成器/迭代器 – 2009-10-12 18:28:28

+2

只是FYI,你不需要额外的parens。 max()的父类可以执行双重任务:它们可以是调用max()的函数的父元素,也可以是生成器表达式周围的元素。尝试一下! :-) – steveha 2009-10-12 18:41:28

0

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

相关问题