在下面的代码中,什么更有效/更'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
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
我倾向于使用try catch选项,但我不确定原因。
答案 0 :(得分:21)
使用dict.get()
:
get(key[, default])
如果
key
在字典中,则返回key的值,否则返回default
。如果 未给出default
,默认为None
,因此此方法永远不会 提出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}
答案 1 :(得分:16)
根据你的python版本,你可能想在这里使用defaultdict
或Counter
,因为它是最合适的。
现在,关于哪种替代品是最蟒蛇的,它取决于你要问的人。一方面,exception-based flow control is sometimes frowned upon,因为异常应该在特殊情况下提出,而不是用作条件。
然而,另一方面,有situations in which you would rather use try / except,因为条件不实用。
最后,从性能的角度来看,这取决于你是否希望你的密钥在大多数时间都存在(一个if
语句有点慢,但是一个例外是慢很多当< / em>它被提升了),如果考虑到性能,你应该在决定之前用两种实现来衡量你的表现。
总而言之,我认为一般的经验法则是默认使用条件,但如果它们更实用/更有意义/给你真正需要的加速,则使用例外。
答案 2 :(得分:10)
更多pythonic是使用专用工具:
from collections import Counter
with open(fname, 'r') as f:
letters = Counter(f.read())
另请注意,has_key
已弃用,以支持in
。
答案 3 :(得分:0)
看看你是否可以使用这个技巧来pythonically地处理异常。
adict = {}
default = None
val = adict.get('dogname', default)
# val will be None rather than raise an exception.