[Python-ideas] Fwd: Using functools.lru_cache only on some arguments of a function

Michael Selik mike at selik.org
Tue Jan 12 21:13:25 EST 2016


On Tue, Jan 12, 2016 at 6:26 PM Franklin? Lee <leewangzhong+python at gmail.com>
wrote:

> On Sun, Jan 10, 2016 at 3:27 AM, Bill Winslow <bunslow at gmail.com> wrote:
> > Sorry for the late reply everyone.
> >
> > I think relying on closures, while a solution, is messy. I'd still much
> > prefer a way to tell lru_cache to merely ignore certain arguments.
>
> Wait, why is it messy? The function is created inside the outer
> function, and never gets released to the outside. I think it's
> cleaner, because it's encapsulating the recursive part, the memo, and
> the cached work. Besides, `lru_cache` is implemented using a closure,
> and your solution of passing a key function might be used with a
> closure on a nested function.
>
> If you're solving dynamic programming puzzles, an outer/inner pairing
> of non-recursive/recursive represents the fact that your memoization
> can't be reused for different instances of the same problem. (See, for
> example, Edit Distance
> (https://web.stanford.edu/class/cs124/lec/med.pdf), in which your
> recursive parameters are indices into your non-recursive parameters.)
>
>
> > I've further considered my original proposal, and rather than naming it
> > "arg_filter", I realized that builtins like sorted(), min(), max(), etc
> all
> > already have the exact same thing -- a "key" argument which transforms
> the
> > elements to the user's purpose. (In the sorted/min/max case, it's called
> on
> > the elements of the argument rather than the argument itself, but it's
> still
> > the same concept.) So basically, my original proposal with renaming from
> > arg_filter to key, is tantamount to extending the same functionality from
> > sorted/min/max to lru_cache as well.
>
> I like this conceptually, because the `key` parameter sort of lets you
> customize the cache dict (or whatever). You can use, for example,
> `str.lower` (though not directly).
>
> Note that the key parameter in those other functions allows you to
> call the key function only once per element, which is impossible for
> this.
>
> Should it be possible to specify a tuple for `key` to transform each
> arg separately? In your case, you might pass in `(None, lambda x: 0)`
> to specify that the first parameter shouldn't be transformed, and the
> second parameter should be considered constant. But that's very
> confusing: should `None` mean "ignore", or "don't transform" (like
> `filter`)? Or we can use `False` for "ignore", perhaps.
>

I think his intention was to mimic the ``key`` argument of sorted, which
expects a function that takes 1 and only 1 positional argument.

Perhaps it's best to see the exact use case and a few other examples, to
get a better idea for the specifics, before implementing this feature?

On Sun, Jan 10, 2016 at 2:03 PM, Michael Selik <mike at selik.org> wrote:
> > Shouldn't the key function be called with ``key(*args, **kwargs)``?
>
> Does `lru_cache` know how to deal with passing regular args as kwargs?
>

Now that you mention it, I realized it treats the two differently.
``def foo(x): pass`` would store ``foo(42)`` and ``foo(x=42)`` as different
entries in the cache.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160113/ada176ac/attachment.html>


More information about the Python-ideas mailing list