zenpoy zenpoy - 3 months ago 16
Python Question

Python: try except KeyError vs if has_key()

In the following code, what's more efficient / more 'Pythonic'? using a try-catch clause or a if-else clause?

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


I tend to go with the try catch option, but I'm not sure why.

Answer

Depending on your python version, you might want to use a defaultdict or a Counter here, as it's the most appropriate.

Now, regarding which alternative is the most pythonic, it depends on the people you're going to ask. On the one hand, exception-based flow control is sometimes frowned upon, as exceptions are supposed to be raised in exceptional situations, and not to be used as conditionals.

On the other hand, however, there are situations in which you would rather use try / except because conditionals would not be practical.

Finally, from a performance standpoint, it depends on whether you expect your key to be there most of the time (An if statement is a bit slower, but an exception is a lot slower when it's raised), and if performance is a concern, you should measure your performance with both implementations before deciding.


All in all, I think that a general rule of thumb would be to use conditionals by default, but use exceptions if they are more practical / make more sense / give you speedups that you really need.