Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dict.pop or dict.get and evaluation

Consider the following code:

>>> def default_answer():
...     print "Default was required!"
...     return 100
... 
>>> g = { 'name': 'Jordan', 'age': 35 }
>>> result = g.get('age', default_answer())
Default was required!
>>> result = g.pop('age', default_answer())
Default was required!

Notice that whether g contains the expected key or not, default_answer is called. This makes sense programmatically but if default_answer was computationally expensive this would be a hassle (to run a lot of code to create a value that was going to be thrown away).

The only way I can think of writing this without always calling default_answer is:

result = g.pop('age', False) or default_answer()

Is this the best way to do it?

(Note that I'm aware that replacing default_answer with an object with lazy evaluation would also solve part of this problem, but that's outside the scope of this question).

like image 419
Jordan Reiter Avatar asked Aug 27 '12 18:08

Jordan Reiter


2 Answers

No, this is not the best way to do this, since the result of g.pop() might be "falsy". Use try/except instead:

try:
    result = g.pop('age')
except KeyError:
    result = default_answer()

This idiom is called EAFP and is usually preferred over LBYL for various reasons:

  1. It avoids looking up the key twice (which is not an issue with an actual dict, but might be suboptimal with other mappings).

  2. It avoids a race condition in threaded code.

  3. Many people find it easier to read.

like image 144
Sven Marnach Avatar answered Sep 27 '22 21:09

Sven Marnach


That is an okay way as long as you know that any boolean-false value (not just False but also empty string, empty list, etc.) should be replaced by your default. You can always do it explicitly:

if 'age' in g:
    result = g['age']
else:
    result = default_answer()

(Or an equivalent version with try/except where you read the value first and do the default in an except clause. Which one is better depends on whether you expect the missing-value case to be common or uncommon.)

like image 43
BrenBarn Avatar answered Sep 27 '22 20:09

BrenBarn