【问题标题】:Checking for membership in dictionary: exceptions or set?检查字典中的成员资格:例外还是设置?
【发布时间】:2012-12-22 21:57:22
【问题描述】:

我想处理一个元素列表ls,每个元素在字典d 中可能有也可能没有对应的元素。我可以想到两种方法来做到这一点。这里,s 是所有作为d 键的元素的集合。在构造 d 时,构造 s 也是微不足道的,所以把它当作给定的。

for e in ls:
    if e in s:
        process(d[e])

for e in ls:
    try:
        process(d[e])
    except KeyError:
        pass

在这两者中,哪个更快?此外,我听说 Python 使用“请求宽恕,而不是许可”的原则。这是否意味着在一般测试中使用if 语句会比使用异常慢?

【问题讨论】:

  • 哪个更快取决于未命中的频率,请参阅Python Forgiveness vs. Permission and Duck Typing。大量未命中:使用in 测试。少有遗漏:使用例外。
  • 处理ls元素的顺序重要吗?
  • @MartijnPieters 不,它没有。
  • 哪个更快有关系吗?假设您的 process 方法做了一些实际的工作,我猜想该方法的运行时间将使这两种方法之间的任何差异都相形见绌。
  • @MarkByers 可能是真的,但出于好奇,我仍然想知道 Python 是如何做事的。

标签: python dictionary set


【解决方案1】:

如果顺序无关紧要,请使用交叉点:

for e in s.intersection(ls):
    # only elements that are in `s` *and* `ls` are iterated over
    process(d[e])

无论如何,你的大部分时间都可能会花在process() 上,所以不要进行微优化。而是优化可读性(在合理范围内)。

至于in 测试与异常处理的选择:如果未命中数较低(异常相对较少),异常处理会更快,但如果未命中很多,in 测试将是比处理大量异常更快。如果您真的很在意,请使用timeit module 找到平衡点。见my answer on the subject on Programmers.SE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 2013-02-03
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多