Mix lambda and list comprehension?

Discussion in 'Python' started by Peter Barth, Jul 15, 2003.

  1. Peter Barth

    Peter Barth Guest

    Hi,
    trying to mix lambda expresions and list comprehension
    doesn't seem to work.
    ---
    >>> [lambda x:x+y for y in range(10)][9](2)

    11
    >>> [lambda x:x+y for y in range(10)][4](2)

    11
    ---
    I expected the second expression to return 6.
    What did I do wrong? Any hints?
    Thanks
    - Peter
     
    Peter Barth, Jul 15, 2003
    #1
    1. Advertising

  2. Try this:

    >>> [lambda x, y=y:x+y for y in range(10)][4](2)

    6


    It is important to bind y in a closure at the time
    the lambda is defined. Otherwise, y remains unbound
    until you invoke the function call. At that time, the most
    recent value of y is the last value in the range loop (namely, 9).


    Raymond Hettinger



    "Peter Barth" <> wrote in message
    news:...
    > Hi,
    > trying to mix lambda expresions and list comprehension
    > doesn't seem to work.
    > ---
    > >>> [lambda x:x+y for y in range(10)][9](2)

    > 11
    > >>> [lambda x:x+y for y in range(10)][4](2)

    > 11
    > ---
    > I expected the second expression to return 6.
    > What did I do wrong? Any hints?
    > Thanks
    > - Peter
     
    Raymond Hettinger, Jul 15, 2003
    #2
    1. Advertising

  3. (Peter Barth) wrote in message news:<>...
    > Hi,
    > trying to mix lambda expresions and list comprehension
    > doesn't seem to work.
    > ---
    > >>> [lambda x:x+y for y in range(10)][9](2)

    > 11
    > >>> [lambda x:x+y for y in range(10)][4](2)

    > 11
    > ---
    > I expected the second expression to return 6.
    > What did I do wrong? Any hints?
    > Thanks
    > - Peter


    It is a scope issue. The last value for y is used for all
    the created lambdas. All lambdas users are bitten by that,
    soon or later. The solution is to make y local to the
    lambda function, with the optional argument trick:

    >>> [lambda x,y=y:x+y for y in range(10)][4](2)

    6

    Michele
     
    Michele Simionato, Jul 15, 2003
    #3
  4. Peter Barth

    Peter Barth Guest

    Thanks a lot, works fine.
    However, the solution does not really feel "pythonesque".
    Is it considered a usability bug or fine as is?
    - Peter

    "Raymond Hettinger" <> wrote in message news:<hMNQa.1134$>...
    > Try this:
    >
    > >>> [lambda x, y=y:x+y for y in range(10)][4](2)

    > 6
    >
    >
    > It is important to bind y in a closure at the time
    > the lambda is defined. Otherwise, y remains unbound
    > until you invoke the function call. At that time, the most
    > recent value of y is the last value in the range loop (namely, 9).
    >
    >
    > Raymond Hettinger
    >
    >
    >
    > "Peter Barth" <> wrote in message
    > news:...
    > > Hi,
    > > trying to mix lambda expresions and list comprehension
    > > doesn't seem to work.
    > > ---
    > > >>> [lambda x:x+y for y in range(10)][9](2)

    > 11
    > > >>> [lambda x:x+y for y in range(10)][4](2)

    > > 11
    > > ---
    > > I expected the second expression to return 6.
    > > What did I do wrong? Any hints?
    > > Thanks
    > > - Peter
     
    Peter Barth, Jul 15, 2003
    #4
  5. (Bengt Richter) wrote in message news:<bf3pjm$gsl$0@216.39.172.122>...
    > On 15 Jul 2003 05:41:02 -0700, (Michele Simionato) wrote:
    >
    > > (Peter Barth) wrote in message news:<>...
    > >> Hi,
    > >> trying to mix lambda expresions and list comprehension
    > >> doesn't seem to work.
    > >> ---
    > >> >>> [lambda x:x+y for y in range(10)][9](2)

    > 11
    > >> >>> [lambda x:x+y for y in range(10)][4](2)
    > >> 11
    > >> ---
    > >> I expected the second expression to return 6.
    > >> What did I do wrong? Any hints?
    > >> Thanks
    > >> - Peter

    > >
    > >It is a scope issue. The last value for y is used for all
    > >the created lambdas. All lambdas users are bitten by that,
    > >soon or later. The solution is to make y local to the
    > >lambda function, with the optional argument trick:
    > >
    > >>>> [lambda x,y=y:x+y for y in range(10)][4](2)

    > >6

    >
    > or you could capture y as constants in the lambdas ;-)
    >
    > >>> [eval('lambda x:x+%s'%y) for y in range(10)][4](2)

    > 6
    >
    >
    > Regards,
    > Bengt Richter


    Thanks to God, there is a smile in your post!!

    ;)

    Michele
     
    Michele Simionato, Jul 17, 2003
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Vedran Furac(
    Replies:
    4
    Views:
    357
    Marc 'BlackJack' Rintsch
    Dec 19, 2008
  2. Daniel Fetchinson

    lambda in list comprehension acting funny

    Daniel Fetchinson, Jul 11, 2012, in forum: Python
    Replies:
    45
    Views:
    736
    Robert Miles
    Aug 16, 2012
  3. Daniel Fetchinson

    Re: lambda in list comprehension acting funny

    Daniel Fetchinson, Jul 11, 2012, in forum: Python
    Replies:
    4
    Views:
    227
    88888 Dihedral
    Jul 14, 2012
  4. Jurko Gospodnetić

    Re: lambda in list comprehension acting funny

    Jurko Gospodnetić, Jul 11, 2012, in forum: Python
    Replies:
    0
    Views:
    219
    Jurko Gospodnetić
    Jul 11, 2012
  5. Daniel Fetchinson

    Re: lambda in list comprehension acting funny

    Daniel Fetchinson, Jul 11, 2012, in forum: Python
    Replies:
    0
    Views:
    203
    Daniel Fetchinson
    Jul 11, 2012
Loading...

Share This Page