[Tutor] Function in a data structure

Rodrigues op73418@mail.telepac.pt
Tue Jun 24 07:40:02 2003


> -----Original Message-----
> From: tutor-admin@python.org
> [mailto:tutor-admin@python.org]On Behalf Of
> Tim Johnson
> Sent: terca-feira, 24 de Junho de 2003 4:32
> To: Rodrigues
> Cc: tutor@python.org
> Subject: Re: [Tutor] Function in a data structure
>
>
> Hello Rodgrigues:
>
> * Rodrigues <op73418@mail.telepac.pt> [030623 17:32]:
> > > -----Original Message-----
> > > From: tutor-admin@python.org
> > > [mailto:tutor-admin@python.org]On Behalf Of
> > > Tim Johnson
> > >
> > >
> > > Hello All:
> > >     I'd like to put a function in data structure
> > >     and execute it as part of processing the
> > >     structure.
> > > I have
> > > >>fd = {'func':[lambda x: x**2]}
> > >
> >
> > Here you a have a dictionary with one pair. The key is the string
> > 'func', but the value is a *list* of one element, precisely the
> > function object lambda x: x**2. Ditch the [] and your
> code below will
> > (almost) work.
> >
> > > How may I execute the lambda statement which
> > > is the value for fd['func']?
> > > I've tried:
> > >   apply(fd['func'],(2))
> > >   and apply(fd['func'],2)
> > >   with no luck
>
>   I have found that I can call this function with
>   >>> fd['func'][0](2)
>   4
>   :-) Works for me. But I am still intrigued by your
>       solution with apply, but do not follow completely.
>       Please excuse my newbie-lack-of-insite here.
>

Yes, it works. To see why, note the following chain of bindings:

fd --> {'func':[lambda x: x**2]}
fd['func'] --> [lambda x: x**2]
fd['func'][0] --> lambda x: x**2

So fd['func'][0] is bound to the function object lambda x: x**2, and
as such you can call it as you call any other function objects, e.g.

>>> fd['func'][0](2)

My comment above about ditching the [], is that in *this context* they
are of no use. It's a whole different story if in the code from which
this was taken you *do need* a list as a value in the dictionary.

[Example snipped]

> >
> > >>> apply(lambda x:x**2, (2,))
>
>  Rodrigues, you are using apply without referencing
>  the 'lambda' statement from my original dictionary
>  example. So I am still unclear on how you would use
>  apply to execute the 'lambda' as a member of the
>  dictionary. Sorry to be so dense, but maybe I
>  shouldn't try to cook dinner and code at the same
>  time.
>
>   I find that apply(fd['func'][0],(2,)) also
>   works, is this what you meant?

Yes, that's what I meant. I jumped some hoops and introduced the
lambda directly instead of the dictionary -- sorry about that.

Notice though that the form of apply is:

apply(<callable>, <tuple of args> [, <dict of named args>])

Since fd['func'][0] is bound to lambda x:x**2, a callable, it works.
callables are functions, methods (bound and unbound), classes and
instances of classes defining __call__. Some examples:

>>> def test():
... 	return "This is a test."
...
>>> apply(test, ())
'This is a test.'
>>> #apply with classes.
>>> apply(tuple, ([1, 2, 3],))
(1, 2, 3)
>>> #Apply with methods.
>>> a = []
>>> apply(a.append, (1,))
>>> print a
[1]
>>> #Apply with instances of classes defining __call__
>>> class Test(object):
... 	def __call__(self):
... 		return "I am %r." % self
...
>>> a = Test()
>>> print apply(a, ())
I am <__main__.Test object at 0x010FDE40>.
>>>

Hope that helps,
G. Rodrigues