lambda in list comprehension acting funny

Ian Kelly ian.g.kelly at gmail.com
Thu Jul 12 12:53:25 EDT 2012


On Wed, Jul 11, 2012 at 9:59 PM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> On Wed, 11 Jul 2012 08:41:57 +0200, Daniel Fetchinson wrote:
>
>> funcs = [ lambda x: x**i for i in range( 5 ) ]
>
> Here's another solution:
>
> from functools import partial
> funcs = [partial(lambda i, x: x**i, i) for i in range(5)]
>
>
> Notice that the arguments i and x are defined in the opposite order.
> That's because partial only applies positional arguments from the left.
> If there was a "right partial" that applies from the right, we could use
> the built-in instead:
>
> funcs = [rpartial(pow, i) for i in range(5)]

You know, partial does handle keyword arguments correctly:

funcs = [partial(lambda x, i: x ** i, i=i) for i in range(5)]

This might be bad practice though if there are other arguments to the
right of the keywords that the eventual caller might want to specify,
as those arguments would then effectively be keyword-only.  The error
message in that case is not particularly illuminating, either:

>>> def f(a, b, c):
...   return (a, b, c)
...
>>> g = partial(f, b=42)
>>> g(3, 14)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() got multiple values for keyword argument 'b'

It would be a bit clearer if it instead noted that 'c' were
keyword-only in the 'g' argspec.

Cheers,
Ian



More information about the Python-list mailing list