pythonfunctiondictionarysetdefault

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?


Solution

  • 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)