s1m0n3
s1m0n3

Reputation: 43

Strange behavior when passing a function as second parameter of the `setdefault` dictionary method

I don't understand the behavior of setdefault in this scenario:

def f(x):
    return x+1

dct = {5: 15}

print(dct.setdefault(5, f(5)))

The key 5 is in the dictionary, but instead of returning the value 15 immediately, it wastes time computing the function at the second argument. In the end, it discards the output of f and returns 15.

Is this a bug? What is its purpose?

Upvotes: 0

Views: 81

Answers (2)

Juan Federico
Juan Federico

Reputation: 81

In Python all arguments must be evaluated before the function is called. It would be a 'performant' behavior for this case, but could lead to consistency issues for others.

Upvotes: 1

tdelaney
tdelaney

Reputation: 77357

Python allows you to use expressions as parameters to a function. In fact, you could view all parameters as expressions. Python will evaluate all of the parameter expressions from left to right, resolving each to a single object. A function object is created, the list is expanded into the parameter set for the function, and finally the function is called.

In dct.setdefault(5, f(5)), python has no idea whether a function parameter expression will be used or not. And it can't evaluate the expression after the call is made. So, f(5) is resolved and the function is called.

If a function is expensive, then setdefault is not the tool for you. Use "not in" instead.

if 5 not in dct:
    dct[5] = f(5)

Upvotes: 2

Related Questions