Dictionary of Functions
Joshua Landau
joshua.landau.ws at gmail.com
Thu Nov 15 20:41:03 CET 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