Search code examples
pythonmemoization

Prevent calling a function more than once if the parameters have been used before


I would like a way to limit the calling of a function to once per values of parameters.

For example

def unique_func(x):
    return x

>>> unique_func([1])
[1]
>>> unique_func([1])
*** wont return anything ***
>>> unique_func([2])
[2]

Any suggestions? I've looked into using memoization but not established a solution just yet.

This is not solved by the suggested Prevent a function from being called twice in a row since that only solves when the previous func call had them parameters.


Solution

  • Memoization uses a mapping of arguments to return values. Here, you just want a mapping of arguments to None, which can be handled with a simple set.

    def idempotize(f):
        cache = set()
        def _(x):
            if x in cache:
                return
            cache.add(x)
            return f(x)
        return _
    
    
    @idempotize
    def unique_fun(x):
        ...
    

    With some care, this can be generalized to handle functions with multiple arguments, as long as they are hashable.

    def idempotize(f):
        cache = set()
        def _(*args, **kwargs):
            k = (args, frozenset(kwargs.items()))
            if k in cache:
                return
            return f(*args, **kwargs)
        return _