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).
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:
It avoids looking up the key twice (which is not an issue with an actual dict
, but might be suboptimal with other mappings).
It avoids a race condition in threaded code.
Many people find it easier to read.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With