python-3.xfunctioncaching

How can I deploy cache when the order of arguments doesn't matter?


Say I have a function func, which happens to have the property that func(a, b) == func(b, a) is always True.

Then say I decorate the function with the @cache decorator from functools. My understanding of that decorator is that the first time func(a, b) is called its result gets cached so that whenever func(a, b) is called again it can just look-up the result instead of calling the function again.

Now, if I understand correctly, if I run func(b, a) the function will be called, as the specific input tuple (b, a) has not yet been cached. However, given we know func(b, a) has the same result as func(a, b), is there a way to leverage the cache in this instance?

In short, is there a way to ignore the order of arguments when caching?


Solution

  • I would be tempted to just sort the parameters if you wanted to cache the results where the order of parameters did not matter.

    import functools
    
    def sort_parameters(func):
        return lambda *args, **kwargs: func(*sorted(args), **kwargs)
    
    @sort_parameters
    @functools.cache
    def mult(a, b):
        print("method actually called")
        return a * b
    
    print(mult(2, 3))
    print(mult(2, 3))
    print(mult(3, 2))
    

    Should give you:

    method actually called
    6
    6
    6