0

I have got a project, where I have to do this very frequently:

if "something" in dict:
    some_var = dict["something"]
    del dict["something"]
else:
    error_handler_or_other_stuff()

However I have the idea to use this:

try:
    some_var = dict.pop("something")
except KeyError:
    error_handler_or_other_stuff()

My question is: in general, how "fast" try - except constructs are to handle exceptions? Is it OK to use it a lot, or it's still faster to do the stuff "manually". Also sometimes I have the situation where I have to convert value to integer:

try:
    some_var = int(dict.pop("something"))
except KeyError:
    error_handler_or_other_stuff("no such key")
except ValueError:
    error_handler_or_other_stuff("bad value for key")

Now the solution with exceptions seems to be quite nice, since I can do both of the checks in one step, also I removed the original key/value pair from dict, which is part of the problem. So I can tell at least: it looks like an elegant solution. However I am not sure it's faster or if it has other disadvantages I should worry about.

4 Answers 4

5

Which construct makes your code easier to understand and maintain? Pick that one.

If the resulting code is too slow, then go back and consider whether a different error handling strategy is more efficient.

Sign up to request clarification or add additional context in comments.

1 Comment

+1 even though docs says It's easier to ask forgiveness than permission. Sometimes it just doesn't make sense.
4

Why not use dict.get or dict.pop with the default parameter?

1 Comment

In his example, he's removing items from the dict as he retrieves them.
3

These kind of performance questions are easily answered using the timeit module:

setup = '''
d = {'a': 1}
k = 'b'
'''

LBYL = '''
if k in d:
    pass
else:
    pass
'''

EAPF = '''
try:
    d[k]
except KeyError:
    pass
'''

from timeit import Timer

print min(Timer(LBYL, setup).repeat(7, 1000000))
print min(Timer(EAPF, setup).repeat(7, 1000000))

The results show 0.0546 for the if/else approach and 1.3370 for the try/except approach. The latter is about 25 times slower than the former.

That being said, you should generally use whatever expresses the clearest code.

Sidenote: the two approaches give different answers for subclasses of dict that define missing to return a value.

Comments

3

Exceptions are not particularly slow. Obviously there is a lot more going on in exception handling than in a simple if, but unless you're doing it literally a million times per second, the speed difference is negligible.

Your example is so trivial that there is no reason to worry about speed to begin with. Micro-optimizations like that cost more time just thinking about them than you could ever save using them.

The code you've given is absolutely fine, that's what exceptions are there for.

1 Comment

Measurements show that exception handling is dramatically slower than the equivalent if-else approach. Of course, whether or not that makes a difference depends on how many time your call it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.