Mix lambda and list comprehension?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Peter Barth

    Mix lambda and list comprehension?

    Hi,
    trying to mix lambda expresions and list comprehension
    doesn't seem to work.
    ---[color=blue][color=green][color=darkred]
    >>> [lambda x:x+y for y in range(10)][9](2)[/color][/color][/color]
    11[color=blue][color=green][color=darkred]
    >>> [lambda x:x+y for y in range(10)][4](2)[/color][/color][/color]
    11
    ---
    I expected the second expression to return 6.
    What did I do wrong? Any hints?
    Thanks
    - Peter
  • Raymond Hettinger

    #2
    Re: Mix lambda and list comprehension?

    Try this:
    [color=blue][color=green][color=darkred]
    >>> [lambda x, y=y:x+y for y in range(10)][4](2)[/color][/color][/color]
    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" <peter.barth@ t-online.de> wrote in message
    news:6f5b3f88.0 307142302.1a153 [email protected] gle.com...[color=blue]
    > Hi,
    > trying to mix lambda expresions and list comprehension
    > doesn't seem to work.
    > ---[color=green][color=darkred]
    > >>> [lambda x:x+y for y in range(10)][9](2)[/color][/color]
    > 11[color=green][color=darkred]
    > >>> [lambda x:x+y for y in range(10)][4](2)[/color][/color]
    > 11
    > ---
    > I expected the second expression to return 6.
    > What did I do wrong? Any hints?
    > Thanks
    > - Peter[/color]


    Comment

    • Michele Simionato

      #3
      Re: Mix lambda and list comprehension?

      [email protected] (Peter Barth) wrote in message news:<6f5b3f88. 0307142302.1a15 [email protected] ogle.com>...[color=blue]
      > Hi,
      > trying to mix lambda expresions and list comprehension
      > doesn't seem to work.
      > ---[color=green][color=darkred]
      > >>> [lambda x:x+y for y in range(10)][9](2)[/color][/color]
      > 11[color=green][color=darkred]
      > >>> [lambda x:x+y for y in range(10)][4](2)[/color][/color]
      > 11
      > ---
      > I expected the second expression to return 6.
      > What did I do wrong? Any hints?
      > Thanks
      > - Peter[/color]

      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:
      [color=blue][color=green][color=darkred]
      >>> [lambda x,y=y:x+y for y in range(10)][4](2)[/color][/color][/color]
      6

      Michele

      Comment

      • Peter Barth

        #4
        Re: Mix lambda and list comprehension?

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

        "Raymond Hettinger" <vze4rx4y@veriz on.net> wrote in message news:<hMNQa.113 4$I4.740@nwrdny 01.gnilink.net> ...[color=blue]
        > Try this:
        >[color=green][color=darkred]
        > >>> [lambda x, y=y:x+y for y in range(10)][4](2)[/color][/color]
        > 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" <peter.barth@ t-online.de> wrote in message
        > news:6f5b3f88.0 307142302.1a153 [email protected] gle.com...[color=green]
        > > Hi,
        > > trying to mix lambda expresions and list comprehension
        > > doesn't seem to work.
        > > ---[color=darkred]
        > > >>> [lambda x:x+y for y in range(10)][9](2)[/color][/color]
        > 11[color=green][color=darkred]
        > > >>> [lambda x:x+y for y in range(10)][4](2)[/color]
        > > 11
        > > ---
        > > I expected the second expression to return 6.
        > > What did I do wrong? Any hints?
        > > Thanks
        > > - Peter[/color][/color]

        Comment

        • Michele Simionato

          #5
          Re: Mix lambda and list comprehension?

          [email protected] (Bengt Richter) wrote in message news:<bf3pjm$gs [email protected]. 122>...[color=blue]
          > On 15 Jul 2003 05:41:02 -0700, [email protected] (Michele Simionato) wrote:
          >[color=green]
          > >peter.barth@ t-online.de (Peter Barth) wrote in message news:<6f5b3f88. 0307142302.1a15 [email protected] ogle.com>...[color=darkred]
          > >> 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)[/color][/color]
          > 11[color=green][color=darkred]
          > >> >>> [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[/color]
          > >
          > >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:
          > >[color=darkred]
          > >>>> [lambda x,y=y:x+y for y in range(10)][4](2)[/color]
          > >6[/color]
          >
          > or you could capture y as constants in the lambdas ;-)
          >[color=green][color=darkred]
          > >>> [eval('lambda x:x+%s'%y) for y in range(10)][4](2)[/color][/color]
          > 6
          >
          >
          > Regards,
          > Bengt Richter[/color]

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

          ;)

          Michele

          Comment

          Working...