Dictionary of Functions

Joshua Landau joshua.landau.ws at gmail.com
Thu Nov 15 14:41:03 EST 2012


On 15 November 2012 17:13, Chris Kaynor <ckaynor at zindagigames.com> wrote:

> On Thu, Nov 15, 2012 at 8:04 AM, Kevin Gullikson
> <kevin.gullikson at gmail.com> wrote:
> > Hi all,
> >
> > I am trying to make a dictionary of functions, where each entry in the
> > dictionary is the same function with a few of the parameters set to
> specific
> > parameters. My actual use is pretty complicated, but I managed to boil
> down
> > the issue I am having to the following example:
> >
> > In [1]: def test_fcn(a, x):
> >    ...:     return a*x
> >    ...:
> >
> > In [2]: fcn_dict = {}
> >
> > In [3]: for i in [1,2,3]:
> >    ...:     fcn_dict[i] = lambda x: test_fcn(i, x)
> >    ...:
>
> In this case, I would recommend using functools.partial instead of a
> lambda.
> It will solve this problem (although MRAB's solution will as well), is
> trivially faster (likely insignificant in any real application), and,
> IMO, clearer:
>
> for i in [1,2,3]:
>     fcn_dict[i] = functools.partial(test_fcn, i)
>
> Note that this only works if you are either only specifying the first
> arguments by position, or specifying arguments by keyword. There is no
> way to specify the second argument by position; you'd have to pass it
> as a keyword argument.
>

Another way to do this is by making a factory function:

>>> def factor_multiplier(factor):
...     def factor_multiply(target):
...             return factor * target
...     return factor_multiply
...

Testing it:

>>> trippler = factor_multiplier(3)
>>> trippler
<function factor_multiplier.<locals>.factor_multiply at 0x7ffeb5d6db90>
>>> trippler(10)
30
>>> doubler = factor_multiplier(2)
>>> doubler(15)
30
>>> doubler(trippler(1))
6
>>>

Solving your problem:

>>> function_dict = {}
>>> for i in range(100):
...     function_dict[i] = factor_multiplier(i)
...
>>>
>>> function_dict[42](2)
84
>>> function_dict[20](3)
60
>>>

This is definitely longer that Chris' approach, but it's more powerful
overall. It's worth learning and using both.

In a sense, you were close, but you were just not catching the variable:

>>> function_dict.clear()
>>> for i in range(100):
...     function_dict[i] = (lambda i: lambda x: x*i)(i)
...
>>> function_dict[19](2)
38
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20121115/4810bcbd/attachment.html>


More information about the Python-list mailing list