python dict get method runs the second argument even when key is in dict
Question:
according to the doc, the get method of a dict can have two argument: key and a value to return if that key is not in the dict. However, when the second argument is a function, it’ll run regardless of whether the key is in the dict or not:
def foo():
print('foo')
params={'a':1}
print(params.get('a', foo()))
# foo
# 1
As shown above, the key a
is in the dict, but foo()
still runs. What happens here?
Answers:
This is a common misconception, the arguments must be evaluated whether or not they are used by the function, for example:
>>> def f(x, y, z): pass
...
>>> f(print(1), print(2), print(3))
1
2
3
So the print(1), print(2), print(3)
statements are executed even if the function f
does not use the arguments. You can use try
except
instead to evaluate foo()
only when it is needed:
try:
x = params['a']
except KeyError:
x = foo()
params.get('a', foo())
Your second argument is not a function, it’s a function call. So the .get()
method calls it to obtain its second argument.
To put your function as a second argument, you have to remove parenthesis after it:
params.get('a', foo)
according to the doc, the get method of a dict can have two argument: key and a value to return if that key is not in the dict. However, when the second argument is a function, it’ll run regardless of whether the key is in the dict or not:
def foo():
print('foo')
params={'a':1}
print(params.get('a', foo()))
# foo
# 1
As shown above, the key a
is in the dict, but foo()
still runs. What happens here?
This is a common misconception, the arguments must be evaluated whether or not they are used by the function, for example:
>>> def f(x, y, z): pass
...
>>> f(print(1), print(2), print(3))
1
2
3
So the print(1), print(2), print(3)
statements are executed even if the function f
does not use the arguments. You can use try
except
instead to evaluate foo()
only when it is needed:
try:
x = params['a']
except KeyError:
x = foo()
params.get('a', foo())
Your second argument is not a function, it’s a function call. So the .get()
method calls it to obtain its second argument.
To put your function as a second argument, you have to remove parenthesis after it:
params.get('a', foo)