Python:尝试除了KeyError vs if has_key()

zen*_*poy 18 python performance

在下面的代码中,什么更有效/更'Pythonic'?使用try-catch子句或if-else子句?

fname = 'AdobeARM.log'

letters = {}

with open(fname,'r') as f:
    for line in f:
        for c in line:
            try:
                letters[c] += 1
            except KeyError:
                letters[c] = 1

print letters
Run Code Online (Sandbox Code Playgroud)

VS.

fname = 'AdobeARM.log'

letters = {}

with open(fname,'r') as f:
    for line in f:
        for c in line:
            if letters.has_key(c):
                letters[c] += 1
            else:
                letters[c] = 1

print letters
Run Code Online (Sandbox Code Playgroud)

我倾向于使用try catch选项,但我不确定为什么.

Ash*_*ary 21

用途dict.get():

get(key[, default])

如果key在字典中,则返回key的值,否则default.如果 default没有给出,则默认为None,因此此方法永远不会引发a KeyError.

换句话说d.get('x', c)相当于d['x'] if 'x' in d else c.

例:

In [24]: d = {'a':1, 'b':2}

In [27]: d['d'] = d.get('d', 0) + 1  # 0 is the default value

In [28]: d
Out[28]: {'a': 1, 'b': 2, 'd': 1}

In [29]: d['d'] = d.get('d', 0) + 1

In [30]: d
Out[30]: {'a': 1, 'b': 2, 'd': 2}
Run Code Online (Sandbox Code Playgroud)

  • @piokuc所以`letters [c] = letters.get(c,0)+ 1`会更好 (3认同)

Tho*_*zco 17

根据您的python版本,您可能希望使用a defaultdictCounterhere,因为它是最合适的.

现在,关于哪种替代品是最蟒蛇的,它取决于你要问的人.一方面,基于异常的流控制有时不受欢迎,因为异常应该在特殊情况下引发,而不是用作条件.

但是,另一方面,在某些情况下,您宁愿使用try/except,因为条件不实用.

最后,从性能的角度来看,这取决于你是否希望你的密钥在大多数时间都存在(一个if语句有点慢,但是它被提升异常会慢很多),如果性能是一个问题,你应该在决定之前用两种实现来衡量你的表现.


总而言之,我认为一般的经验法则是默认使用条件,但如果它们更实用/更有意义/给你真正需要的加速,则使用例外.


geo*_*org 10

更多pythonic是使用专用工具:

from collections import Counter

with open(fname, 'r') as f:
    letters = Counter(f.read())
Run Code Online (Sandbox Code Playgroud)

另请注意,has_key不赞成使用in.