Can someone give me a short explanation?

Jacek Generowicz jacek.generowicz at cern.ch
Mon Apr 5 05:30:53 EDT 2004


"Senthoorkumaran Punniamoorthy" <solution88pro at hotmail.com> writes:

> I found this code in the book text processing with Python. But having
> little difficulty understanding how exactly it works and what should
> be passed as argument? Can someone decode this for me please?
> 
> 
> apply_each = lambda fns, args=[]: map(apply, fns, [args]*len(fns))


"map" is a builtin which applies its first argument (which should be a
function[*]) to the elements coming out of the sequences which are passed
to it as arguments 2,3, ... N, and collects all the results in a list,
which it returns.

[*] Where I say "function" in any of this, I should really be saying
    "callable". If you don't know what this means, ignore it. Not
    important.

In this case, the first argument of "map" is "apply". "apply" is a
builtin which takes a function as its first argument, and applies it
to whatever is in the sequence that is its second argument. (It also
has the ability to deal with keyword args, but forget those for now.)

Take in for granted, for now, that "args" in "[args]*len(fns)" refers
to an empty list. In which case "[args]*len(fns)" creates a list of
empty lists, whose length is equal to the length of the sequence
"fns".

Take it for granted, for now, that "fns" is a sequence of
functions. So, "map(apply, fns, [args]*len(fns))" calls the first
function in the "fns" (giving it no arguments) and remembers the
result, then it calls the next function in "fns" (with no args), and
so on ... then it returns all the results.

Now, "lambda" is a way of creating anonymous functions. You could
created "apply_each" like this:

   def apply_each(fns, args=[]):
       return map(apply, fns, [args]*len(fns))

So, "apply_each" is basically a function, which takes a sequence of
functions, calls them all, and returns all the results in a list.

Let's define a few simple functions, which take no arguments and
return something ... and pass them to apply_each

>>> apply_each = lambda fns, args=[]: map(apply, fns, [args]*len(fns))
>>> def one(): return "one"
... 
>>> def two(): return "two"
... 
>>> def three(): return "three"
... 
>>> apply_each([one,two,three])
['one', 'two', 'three']
>>> 

Now, you could pass a second argument to "apply_args", in which case
it should be a sequence, and the elements of the sequence would be
used as the arguments in each of the calls to the functions you pass.


Without seeing the broader context in which the original appears, it's
difficult to say why it was defined the way it was. Nowadays, I
suspect that many Pythoneers would prefer something like

   def apply_each(fns, args=[]):
       return [ fn(*args) for fn in fns ]

- The stuff appearing after "return" is a List Comprehension.

- The "*" in "fn(*args") means "args is a sequence: pass its contents as
  separate arguments to 'fn'".



More information about the Python-list mailing list