subexpressions

Discussion in 'Python' started by Sergey Dorofeev, Jun 1, 2007.

  1. Hello all!

    Please help, is there way to use sub-expressions in lambda?
    For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    lambda x: sin(x*x)+cos(x*x)
    How to make x*x to be evaluated once?
     
    Sergey Dorofeev, Jun 1, 2007
    #1
    1. Advertising

  2. Sergey Dorofeev

    Peter Otten Guest

    Sergey Dorofeev wrote:

    > Please help, is there way to use sub-expressions in lambda?
    > For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    > lambda x: sin(x*x)+cos(x*x)
    > How to make x*x to be evaluated once?


    >>> (lambda x: [sin(x2) + cos(x2) for x2 in [x*x]][0])(.5) == sin(.5*.5) +

    cos(.5*.5)
    True

    The real answer is of course: Use a function.

    Peter
     
    Peter Otten, Jun 1, 2007
    #2
    1. Advertising

  3. "Peter Otten" <> wrote in message
    news:f3ok60$vp7$03$-online.com...
    > Sergey Dorofeev wrote:
    >
    >> Please help, is there way to use sub-expressions in lambda?
    >> For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    >> lambda x: sin(x*x)+cos(x*x)
    >> How to make x*x to be evaluated once?

    >
    >>>> (lambda x: [sin(x2) + cos(x2) for x2 in [x*x]][0])(.5) == sin(.5*.5) +

    > cos(.5*.5)
    > True
    >
    > The real answer is of course: Use a function.


    But what about something like

    lambda x: sin(y)+cos(y) where y=x*x

    ?
    May be this could be a PEP? If there is no straight way to do this.
     
    Sergey Dorofeev, Jun 1, 2007
    #3
  4. Sergey Dorofeev

    Peter Otten Guest

    Sergey Dorofeev wrote:

    > "Peter Otten" <> wrote in message
    > news:f3ok60$vp7$03$-online.com...
    >> Sergey Dorofeev wrote:
    >>
    >>> Please help, is there way to use sub-expressions in lambda?
    >>> For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    >>> lambda x: sin(x*x)+cos(x*x)
    >>> How to make x*x to be evaluated once?

    >>
    >>>>> (lambda x: [sin(x2) + cos(x2) for x2 in [x*x]][0])(.5) == sin(.5*.5) +

    >> cos(.5*.5)
    >> True
    >>
    >> The real answer is of course: Use a function.

    >
    > But what about something like
    >
    > lambda x: sin(y)+cos(y) where y=x*x
    >
    > ?
    > May be this could be a PEP? If there is no straight way to do this.


    def f(x):
    y = x*x
    return sin(y) + cos(y)

    What is not straightforward about that?

    Peter
     
    Peter Otten, Jun 1, 2007
    #4
  5. "Peter Otten" <> wrote in message
    news:f3oo0p$c7c$03$-online.com...
    >>>> Please help, is there way to use sub-expressions in lambda?
    >>>> For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    >>>> lambda x: sin(x*x)+cos(x*x)
    >>>> How to make x*x to be evaluated once?
    >>>
    >>>>>> (lambda x: [sin(x2) + cos(x2) for x2 in [x*x]][0])(.5) == sin(.5*.5)
    >>>>>> +
    >>> cos(.5*.5)
    >>> True
    >>>
    >>> The real answer is of course: Use a function.

    >>
    >> But what about something like
    >>
    >> lambda x: sin(y)+cos(y) where y=x*x
    >>
    >> ?
    >> May be this could be a PEP? If there is no straight way to do this.

    >
    > def f(x):
    > y = x*x
    > return sin(y) + cos(y)
    >
    > What is not straightforward about that?


    This code is needed once in a map, so I don't want 3+ extra lines.
    Solution seemed so simple...
    I always considered python as languague, where simple things do not require
    extensive coding.
    Moreover, this construction is common thing in functional programming.
     
    Sergey Dorofeev, Jun 1, 2007
    #5
  6. Sergey Dorofeev

    Peter Otten Guest

    Sergey Dorofeev wrote:

    >
    > "Peter Otten" <> wrote in message
    > news:f3oo0p$c7c$03$-online.com...
    >>>>> Please help, is there way to use sub-expressions in lambda?
    >>>>> For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    >>>>> lambda x: sin(x*x)+cos(x*x)
    >>>>> How to make x*x to be evaluated once?
    >>>>
    >>>>>>> (lambda x: [sin(x2) + cos(x2) for x2 in [x*x]][0])(.5) == sin(.5*.5)
    >>>>>>> +
    >>>> cos(.5*.5)
    >>>> True
    >>>>
    >>>> The real answer is of course: Use a function.
    >>>
    >>> But what about something like
    >>>
    >>> lambda x: sin(y)+cos(y) where y=x*x
    >>>
    >>> ?
    >>> May be this could be a PEP? If there is no straight way to do this.

    >>
    >> def f(x):
    >> y = x*x
    >> return sin(y) + cos(y)
    >>
    >> What is not straightforward about that?

    >
    > This code is needed once in a map,


    Perhaps you like [sin(y)+cos(y) for y in (x*x for x in items)] then.

    > so I don't want 3+ extra lines.


    What syntax would you suggest for a lambda enhanced to cover your use case?
    I suppose you will end up with roughly the same number of characters, all
    crammed in one line -- or broken into lines at a random position as it
    happens with overambitious list comprehensions.

    > Solution seemed so simple...


    It /is/ simple.

    > I always considered python as languague, where simple things do not
    > require extensive coding.


    In Python, when conciseness and readability compete, readability tends to
    win (with the inline if...else as a notable exception).

    > Moreover, this construction is common thing in functional programming.


    I can write Haskell in any language :)

    Peter
     
    Peter Otten, Jun 1, 2007
    #6
  7. "Peter Otten" <> wrote in message
    news:f3oret$sit$03$-online.com...

    > What syntax would you suggest for a lambda enhanced to cover your use
    > case?
    > I suppose you will end up with roughly the same number of characters, all
    > crammed in one line -- or broken into lines at a random position as it
    > happens with overambitious list comprehensions.


    Agree, this argument is strong.
     
    Sergey Dorofeev, Jun 1, 2007
    #7
  8. Sergey Dorofeev

    A.T.Hofkamp Guest

    On 2007-06-01, Sergey Dorofeev <> wrote:
    > Hello all!
    >
    > Please help, is there way to use sub-expressions in lambda?
    > For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    > lambda x: sin(x*x)+cos(x*x)
    > How to make x*x to be evaluated once?


    lambda x: (lambda y: sin(y) + cos(y))(x*x)

    Albert
     
    A.T.Hofkamp, Jun 1, 2007
    #8
  9. Sergey Dorofeev

    Steve Holden Guest

    Sergey Dorofeev wrote:
    > "Peter Otten" <> wrote in message
    > news:f3ok60$vp7$03$-online.com...
    >> Sergey Dorofeev wrote:
    >>
    >>> Please help, is there way to use sub-expressions in lambda?
    >>> For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    >>> lambda x: sin(x*x)+cos(x*x)
    >>> How to make x*x to be evaluated once?
    >>>>> (lambda x: [sin(x2) + cos(x2) for x2 in [x*x]][0])(.5) == sin(.5*.5) +

    >> cos(.5*.5)
    >> True
    >>
    >> The real answer is of course: Use a function.

    >
    > But what about something like
    >
    > lambda x: sin(y)+cos(y) where y=x*x
    >
    > ?
    > May be this could be a PEP? If there is no straight way to do this.
    >
    >

    Or maybe it could be made a part of some other language. When
    straightforward mechanisms (in rhis case, function definitins) exist to
    avoid repeated computations it's very unlikely that such mangled
    constructions will be made a part of Python.

    If it *were* considered, you should at least change the "where" to
    "for", and extend it to unpacking assignment to allow

    lambda x, y: (sin(xx+yy) + cos(xx+yy) for xx, yy = x*x, y*y

    regards
    Steve
    --
    Steve Holden +1 571 484 6266 +1 800 494 3119
    Holden Web LLC/Ltd http://www.holdenweb.com
    Skype: holdenweb http://del.icio.us/steve.holden
    ------------------ Asciimercial ---------------------
    Get on the web: Blog, lens and tag your way to fame!!
    holdenweb.blogspot.com squidoo.com/pythonology
    tagged items: del.icio.us/steve.holden/python
    All these services currently offer free registration!
    -------------- Thank You for Reading ----------------
     
    Steve Holden, Jun 1, 2007
    #9
  10. Sergey Dorofeev

    Steve Holden Guest

    Sergey Dorofeev wrote:
    > "Peter Otten" <> wrote in message
    > news:f3oo0p$c7c$03$-online.com...
    >>>>> Please help, is there way to use sub-expressions in lambda?
    >>>>> For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    >>>>> lambda x: sin(x*x)+cos(x*x)
    >>>>> How to make x*x to be evaluated once?
    >>>>>>> (lambda x: [sin(x2) + cos(x2) for x2 in [x*x]][0])(.5) == sin(.5*.5)
    >>>>>>> +
    >>>> cos(.5*.5)
    >>>> True
    >>>>
    >>>> The real answer is of course: Use a function.
    >>> But what about something like
    >>>
    >>> lambda x: sin(y)+cos(y) where y=x*x
    >>>
    >>> ?
    >>> May be this could be a PEP? If there is no straight way to do this.

    >> def f(x):
    >> y = x*x
    >> return sin(y) + cos(y)
    >>
    >> What is not straightforward about that?

    >
    > This code is needed once in a map, so I don't want 3+ extra lines.
    > Solution seemed so simple...
    > I always considered python as languague, where simple things do not require
    > extensive coding.
    > Moreover, this construction is common thing in functional programming.
    >
    >

    Stop thinking of three lines as "extensive coding" and your problem
    disappears immediately.

    regards
    Steve
    --
    Steve Holden +1 571 484 6266 +1 800 494 3119
    Holden Web LLC/Ltd http://www.holdenweb.com
    Skype: holdenweb http://del.icio.us/steve.holden
    ------------------ Asciimercial ---------------------
    Get on the web: Blog, lens and tag your way to fame!!
    holdenweb.blogspot.com squidoo.com/pythonology
    tagged items: del.icio.us/steve.holden/python
    All these services currently offer free registration!
    -------------- Thank You for Reading ----------------
     
    Steve Holden, Jun 1, 2007
    #10
  11. Steve Holden a écrit :
    (snip)
    > Stop thinking of three lines as "extensive coding" and your problem
    > disappears immediately.


    Lol !
    +1 QOTW
     
    Bruno Desthuilliers, Jun 1, 2007
    #11
  12. Sergey Dorofeev

    Paul Boddie Guest

    On 1 Jun, 12:55, Steve Howell <> wrote:
    >
    > FWIW there's the possibility that even without a
    > subexpression syntax, some Python implementations
    > would detect the duplication of x*x and optimize that
    > for you. It would have to know that x*x had no side
    > effects, which I think is a safe assumption even in a
    > dynamic language like Python.


    On the basis of you believing that x is one of the built-in numeric
    types, yes, but how does the compiler know that?

    Paul
     
    Paul Boddie, Jun 1, 2007
    #12
  13. Sergey Dorofeev

    Terry Reedy Guest

    "Sergey Dorofeev" <> wrote in message
    news:f3oj68$1pb8$...
    | How to make x*x to be evaluated once?

    Addendum to the answers already posted: In Python,

    lambda params: expression

    is an inline abbreviation for

    def <lambda>(params): return expression

    except that there is no external binding of the otherwise illegal
    ..func_name '<lambda>'. The resulting function objects are otherwise
    identical.

    After years of discussion, Guido has decided to leave lambda alone for 3.0.
    It will not be neither expanded, nor removed, nor renamed.

    Terry Jan Reedy
     
    Terry Reedy, Jun 1, 2007
    #13
  14. Sergey Dorofeev

    Kay Schluehr Guest

    On Jun 1, 9:51 am, "Sergey Dorofeev" <> wrote:
    > Hello all!
    >
    > Please help, is there way to use sub-expressions in lambda?
    > For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    > lambda x: sin(x*x)+cos(x*x)
    > How to make x*x to be evaluated once?


    lambda x: (lambda y=x*x: math.sin(y)+math.cos(y))()

    Kay
     
    Kay Schluehr, Jun 1, 2007
    #14
  15. Sergey Dorofeev wrote:
    > Please help, is there way to use sub-expressions in lambda?
    > For example, if I want to calculate sin(x^2)+cos(x^2) I must code:
    > lambda x: sin(x*x)+cos(x*x)

    [and later]
    > This code is needed once in a map,


    Peter Otten wrote:
    > Perhaps you like [sin(y)+cos(y) for y in (x*x for x in items)] then.


    Just wanted to emphasize this suggestion so that it doesn't get lost in
    the flood of lambda recommendations. If your code really looks like::

    map(lambda x: sin(x * x) + cos(x * x), items)

    you should be using a list comprehension instead. Using map() here is
    not only more obscure and more verbose, but slower than::

    [sin(x * x) + cos(x * x) for x in items]

    From there, it's a simple nested generator comprehension to pull out
    the subexpression:

    [sin(y) + cos(y) for y in (x * x for x in items)]

    If you aren't yet familiar with list and generator comprehensions, you
    should take a few minutes to look at some of your uses of map() and
    filter and see if you can simplify them using comprehensions instead.

    STeVe
     
    Steven Bethard, Jun 1, 2007
    #15
  16. Sergey Dorofeev

    Paul Boddie Guest

    Steve Howell wrote:
    >
    > The compiler doesn't know the types up front, but if
    > you wanted to do this kind of optimization (and you
    > believed that 95% of x*x cases would benefit from it,
    > and you're willing to sacrifice performance for the 5%
    > of folks that overload multiply), then the compiler
    > could generate bytecode that set the stage for later
    > conditional caching of the first execution of x*x.


    True.

    > You'd then need the execution of the bytecodes at
    > runtime (ceval.c or something called by it) to work in
    > such a way that they only cache the result when side
    > effects are not an issue. At runtime you can reliably
    > detect whether something is still a virgin builtin,
    > correct?


    I've no idea, but I imagine that psyco knows whether or not it has a
    proper built-in number object when it generates specialised code for
    similar cases.

    > To my disclaimer, you would only undertake such an
    > optimization if multiplication were really, really
    > expensive (which I don't think is even true for floats
    > today), and even then you'd proceed cautiously.


    Indeed. Some believe that for "full Python" you can only introduce
    such measures at run-time, although extensive enough analysis of the
    code could perhaps suggest suitable specialisations in advance, as
    presumably demonstrated by Shed Skin.

    Paul
     
    Paul Boddie, Jun 1, 2007
    #16
  17. On Fri, 01 Jun 2007 07:09:50 -0400, Steve Holden wrote:

    >>>>> The real answer is of course: Use a function.
    >>>> But what about something like
    >>>>
    >>>> lambda x: sin(y)+cos(y) where y=x*x
    >>>>
    >>>> ?
    >>>> May be this could be a PEP? If there is no straight way to do this.
    >>> def f(x):
    >>> y = x*x
    >>> return sin(y) + cos(y)
    >>>
    >>> What is not straightforward about that?

    >>
    >> This code is needed once in a map, so I don't want 3+ extra lines.
    >> Solution seemed so simple...
    >> I always considered python as languague, where simple things do not require
    >> extensive coding.
    >> Moreover, this construction is common thing in functional programming.
    >>
    >>

    > Stop thinking of three lines as "extensive coding" and your problem
    > disappears immediately.



    The F-bot once suggested adding a clause to the Zen of Python about
    "writing two lines of code is not a sin" or "cramming two lines of code
    into one is not a virtue" (my paraphrases).


    Check the two alternatives:

    def f(x):
    y = x*x
    return sin(y) + cos(y)

    44 key presses, including tabs and newlines and a blank line after the
    function, but excluding counting the shift key separately.

    lambda x: (lambda y: sin(y) + cos(y))(x*x)

    42 key presses.

    Apart from the extremely minor issue of "namespace pollution", I think
    that speaks for itself.



    --
    Steven.
     
    Steven D'Aprano, Jun 2, 2007
    #17

  18. > ....
    > After years of discussion, Guido has decided
    > to leave lambda alone for 3.0.
    >
    > It will not be neither expanded, nor removed, nor renamed.


    But it still will be as ugh, ugh, ugh-lee
    as a mule walking backwards ..... ;-)


    --
    Stanley C. Kitching
    Human Being
    Phoenix, Arizona


    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Cousin Stanley, Jun 2, 2007
    #18
  19. Sergey Dorofeev

    Terry Reedy Guest

    "Cousin Stanley" <> wrote in message
    news:...
    |
    | > ....
    | > After years of discussion, Guido has decided
    | > to leave lambda alone for 3.0.
    | >
    | > It will not be neither expanded, nor removed, nor renamed.
    |
    | But it still will be as ugh, ugh, ugh-lee
    | as a mule walking backwards ..... ;-)

    Then pretend it was eliminated, as Guido once thought to do, and do not use
    it. And look away when others do ;-)

    tjr
     
    Terry Reedy, Jun 2, 2007
    #19
  20. Sergey Dorofeev

    Stef Mientki Guest

    >
    >
    > Check the two alternatives:
    >
    > def f(x):
    > y = x*x
    > return sin(y) + cos(y)
    >
    > 44 key presses, including tabs and newlines and a blank line after the
    > function, but excluding counting the shift key separately.
    >
    > lambda x: (lambda y: sin(y) + cos(y))(x*x)
    >
    > 42 key presses.
    >
    > Apart from the extremely minor issue of "namespace pollution", I think
    > that speaks for itself.


    and now I've only 60 lines on my screen,
    so what about

    def f(x): y = x*x; return sin(y)+cos(y);

    cheers,
    Stef Mientki
     
    Stef Mientki, Jun 2, 2007
    #20
    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. Replies:
    4
    Views:
    577
  2. Steve Howell

    Re: subexpressions

    Steve Howell, Jun 2, 2007, in forum: Python
    Replies:
    2
    Views:
    274
    Stef Mientki
    Jun 2, 2007
  3. Steve Howell

    Re: subexpressions (OT: math)

    Steve Howell, Jun 2, 2007, in forum: Python
    Replies:
    23
    Views:
    633
    Wildemar Wildenburger
    Jun 4, 2007
  4. sequence points in subexpressions

    , Dec 13, 2009, in forum: C Programming
    Replies:
    114
    Views:
    2,181
    Tim Rentsch
    Jan 12, 2010
  5. trans.  (T. Onoma)

    pre_match and post_match for subexpressions

    trans. (T. Onoma), Oct 24, 2004, in forum: Ruby
    Replies:
    0
    Views:
    109
    trans. (T. Onoma)
    Oct 24, 2004
Loading...

Share This Page