Re: explain this function to me, lambda confusion
Paul McGuire a écrit : On May 19, 11:04 am, Arnaud Delobelle [EMAIL PROTECTED] wrote: Paul McGuire [EMAIL PROTECTED] writes: [...] Could you use it as a decoratore instead? integer = Word(0123456789) @integer.setParseAction def parse_integer(tokens): return int(tokens[0]) I could make your grammar clearer, because you don't mix it with processing code... and no need for lambdas! What a sexy little idiom! You could really apply this to any API method that accepts a callable as a single argument, and pyparsing actually has several of these: setParseAction addParseAction setFailAction setDebugActions (Unfortunately, setDebugActions requires 3 callables for its arguments - one to be run when an expression is about to be parsed, one to be run after parsing is complete, and one to be run if the expression fails to be parsed. So setDebugActions can't be used in this decorator manner.) You just have to provide three decorators instead, one for each callback. Using these methods as decorators deviates from the typical decorator usage model as I understand it - instead of wrapping the provided function within some enclosing setup/teardown code (like lock/unlock, or open-file/close-file, or begin-transaction/commit-transaction), and then returning the created wrapper function, the decorator usage you propose is one in which the decorator uses the provided function with some side-effect (such as setting a property), but then just returns the original function. This is already a well-known decorator pattern. It's used in CherryPy to mark methods that are exposed as request handlers. -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
Bruno Desthuilliers [EMAIL PROTECTED] writes: Paul McGuire a écrit : On May 19, 11:04 am, Arnaud Delobelle [EMAIL PROTECTED] wrote: Paul McGuire [EMAIL PROTECTED] writes: [...] Could you use it as a decoratore instead? integer = Word(0123456789) @integer.setParseAction def parse_integer(tokens): return int(tokens[0]) I could make your grammar clearer, because you don't mix it with processing code... and no need for lambdas! What a sexy little idiom! You could really apply this to any API method that accepts a callable as a single argument, and pyparsing actually has several of these: setParseAction addParseAction setFailAction setDebugActions (Unfortunately, setDebugActions requires 3 callables for its arguments - one to be run when an expression is about to be parsed, one to be run after parsing is complete, and one to be run if the expression fails to be parsed. So setDebugActions can't be used in this decorator manner.) You just have to provide three decorators instead, one for each callback. Using these methods as decorators deviates from the typical decorator usage model as I understand it - instead of wrapping the provided function within some enclosing setup/teardown code (like lock/unlock, or open-file/close-file, or begin-transaction/commit-transaction), and then returning the created wrapper function, the decorator usage you propose is one in which the decorator uses the provided function with some side-effect (such as setting a property), but then just returns the original function. This is already a well-known decorator pattern. It's used in CherryPy to mark methods that are exposed as request handlers. Actually, IIRC the decorator provided by CherryPy is something like (names are probably wrong, as I haven't looked at CherryPy for a while): def exposed(f): f.is_exposed = True return f So it doesn't mutate anything else than the function that it decorates, but changes slightly how the world sees that function. This is in line with classic decorators such as staticmethod, classmethod, etc. -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
On May 19, 5:22 am, Terry Reedy [EMAIL PROTECTED] wrote: Arnaud Delobelle [EMAIL PROTECTED] wrote in message [...] | Note that the same thing can be said about generator expressions, | which are nothing more than anonymous, non-reusable, generator | functions. Right. So if someone posted on genexp confusion, I would suggest 'write a full generator function'. I was just arguing against arguing for the removal of lambda on the basis that it doesn't add any functionality to the language! | Instead these were _added_ to the language! As a convenience. Actually, if one uses more that one for-clause in a generator expression, there is a potential gotcha in relation to name capture. So if that bites, the genexp is not so much a convenience, and one might better write the full function. tjr Yes, IMHO this is a bug, and I wish I had the time to dive into the code to see if I can fix it. -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
inhahe a écrit : Both the responses offer lambda free alternatives. That's fine, and given the terse documentation and problems that I had understanding them, I would agree. So what applications are lambdas suited to? I think the parameterised function model is one. What else? i've hardly ever used lambdas since map() and filter() were replaced by list comprehension. two other uses I can think of for it are: using it as a sorting key (which takes a function and lambdas are perfect for that when a direct function isn't available. for example, lambda x: x.myName), import operator foos.sort(key=operator.attrgetter('myName')) -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
Arnaud Delobelle [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] | On May 19, 5:22 am, Terry Reedy [EMAIL PROTECTED] wrote: | Arnaud Delobelle [EMAIL PROTECTED] wrote in message | [...] | | Note that the same thing can be said about generator expressions, | | which are nothing more than anonymous, non-reusable, generator | | functions. | | Right. So if someone posted on genexp confusion, I would suggest | 'write a full generator function'. | | I was just arguing against arguing for the removal of lambda on the | basis that it doesn't add any functionality to the language! I sort of understood that ;-) Like Guido, I am split on keep/remove. However, I have decided to leave lambda out of my Python-subset executable-pseudocode algorithm language. I have not decided whether or not to include genexps. | | Instead these were _added_ to the language! | | As a convenience. | Actually, if one uses more that one for-clause in a generator expression, | there is a potential gotcha in relation to name capture. So if that bites, | the genexp is not so much a convenience, and one might better write | the full function. | Yes, IMHO this is a bug, and I wish I had the time to dive into the | code to see if I can fix it. If I do include them, I might restrict them to one for-clause because of that glitch, whose details I keep forgetting. tjr | -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
On May 18, 10:41 am, inhahe [EMAIL PROTECTED] wrote: Both the responses offer lambda free alternatives. That's fine, and given the terse documentation and problems that I had understanding them, I would agree. So what applications are lambdas suited to? I think the parameterised function model is one. What else? i've hardly ever used lambdas since map() and filter() were replaced by list comprehension. two other uses I can think of for it are: using it as a sorting key (which takes a function and lambdas are perfect for that when a direct function isn't available. for example, lambda x: x.myName), and I made an irc bot once that certain events had a list of fuctions that would be called after that event. it was like being able to dynamically add and remove event handlers. for example what if you asked the user a question and you wanted to know for the next input whether it was from that user and was an answer to that question. sometimes the function to add would be very simple, so writing a def for it would just be ugly. lambda is handy in defining parse actions in pyparsing. Parse actions are callbacks to be run when an expression within a larger grammar is matched. A common use for parse actions is to do some sort of text or type conversion. The simplest parse actions are called using the list of matched tokens. Here is a subexpression that will convert numeric strings found in a larger grammar to ints: integer = Word(0123456789).setParseAction(lambda tokens: int(tokens[0]) ) Since this returns an actual int, there is no need to junk up the post- parsing code with calls to int(), float(), etc. for these simple conversions. Here is an example parse action that just converts a set of matched words to title case: title = OneOrMore(Word(alphas)).setParseAction(lambda tokens: .join([ t.title() for t in tokens ]) ) print title.parseString(the sun also rises)[0] prints: The Sun Also Rises This second example is about as complex as I'd like to get in a lambda, though. Anything more elaborate than that, and I'd go with a separately defined function. -- Paul -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
Paul McGuire [EMAIL PROTECTED] writes: [...] lambda is handy in defining parse actions in pyparsing. Parse actions are callbacks to be run when an expression within a larger grammar is matched. A common use for parse actions is to do some sort of text or type conversion. The simplest parse actions are called using the list of matched tokens. Here is a subexpression that will convert numeric strings found in a larger grammar to ints: integer = Word(0123456789).setParseAction(lambda tokens: int(tokens[0]) ) Could you use it as a decoratore instead? integer = Word(0123456789) @integer.setParseAction def parse_integer(tokens): return int(tokens[0]) I could make your grammar clearer, because you don't mix it with processing code... and no need for lambdas! -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
On May 19, 11:04 am, Arnaud Delobelle [EMAIL PROTECTED] wrote: Paul McGuire [EMAIL PROTECTED] writes: [...] Could you use it as a decoratore instead? integer = Word(0123456789) @integer.setParseAction def parse_integer(tokens): return int(tokens[0]) I could make your grammar clearer, because you don't mix it with processing code... and no need for lambdas! -- Arnaud What a sexy little idiom! You could really apply this to any API method that accepts a callable as a single argument, and pyparsing actually has several of these: setParseAction addParseAction setFailAction setDebugActions (Unfortunately, setDebugActions requires 3 callables for its arguments - one to be run when an expression is about to be parsed, one to be run after parsing is complete, and one to be run if the expression fails to be parsed. So setDebugActions can't be used in this decorator manner.) Using these methods as decorators deviates from the typical decorator usage model as I understand it - instead of wrapping the provided function within some enclosing setup/teardown code (like lock/unlock, or open-file/close-file, or begin-transaction/commit-transaction), and then returning the created wrapper function, the decorator usage you propose is one in which the decorator uses the provided function with some side-effect (such as setting a property), but then just returns the original function. By returning the original function, we could stack decorators so that multiple expressions could share the same parse action: @articleTitle.setParseAction @movieTitle.setParseAction @bookTitle.setParseAction def upcase_title(tokens): return .join( t.title() for t in tokens ) Here is where I have something of a hitch, with the way pyparsing implements most setXXX methods. setParseAction already returns a value, and the value returned is self. If you have any Smalltalk background, this will seem familiar to you. (Not that I was ever a big-time Smalltalk coder, but this was one language idiom that you learned on Day 0.5 or you were lost forever.) This makes it easy to chain together a constructor and multiple property setters into a single expression: timestamp = Regex(r\d\d(\/\d\d\){2} \d\d(:\d\d) {2}).setParseAction(convertTimeStamp).leaveWhitespace().setDebug() In the case where we have a single parse action shared by multiple expressions, we have to fall back to: def upcase_title(tokens): return .join( t.title() for t in tokens ) articleTitle.setParseAction(upcase_title) movieTitle.setParseAction(upcase_title) bookTitle.setParseAction(upcase_title) But, now that I've looked at this for a while, I may fall back on some other idioms: - just because you *can* do something doesn't mean you *should* do it - explicit is better than implicit Decorator syntax is already a mysterious topic for many newbies, even when used for its normal application. Using a decorator to perform the same function as an explicit set call invokes cleverness at the cost of clarity. Using decorators to replace: def methodX(a,b,c): blah methodX = staticmethod(methodX) with @staticmethod def methodX(a,b,c): blah does have some merits, including DRY. But using decorator syntax as an implicit invocation of a set method? It's just taking advantage of the incidental implementation of the decorator syntax. It would be like implementing the logic of a for-loop using a list comprehension - clever, and yes it can be done, but maybe a bit obscure. -- Paul -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
Paul McGuire [EMAIL PROTECTED] writes: On May 19, 11:04 am, Arnaud Delobelle [EMAIL PROTECTED] wrote: Paul McGuire [EMAIL PROTECTED] writes: [...] Could you use it as a decoratore instead? integer = Word(0123456789) @integer.setParseAction def parse_integer(tokens): return int(tokens[0]) I could make your grammar clearer, because you don't mix it with processing code... and no need for lambdas! -- Arnaud What a sexy little idiom! You could really apply this to any API method that accepts a callable as a single argument, and pyparsing actually has several of these: setParseAction addParseAction setFailAction setDebugActions (Unfortunately, setDebugActions requires 3 callables for its arguments - one to be run when an expression is about to be parsed, one to be run after parsing is complete, and one to be run if the expression fails to be parsed. So setDebugActions can't be used in this decorator manner.) Using these methods as decorators deviates from the typical decorator usage model as I understand it - instead of wrapping the provided function within some enclosing setup/teardown code (like lock/unlock, or open-file/close-file, or begin-transaction/commit-transaction), and then returning the created wrapper function, the decorator usage you propose is one in which the decorator uses the provided function with some side-effect (such as setting a property), but then just returns the original function. I humbly think this is a very good use of decorators; it is one that I frequently take advantage of and until I read this I had never thought of it as deviant :). After all, Python is not a functional language, functions have side-effects and that's that. In a way it is more basic than the 'typical' use, i.e. # Typical use; mutates defined function @staticmethod def foo(bar, baz)... is shorthand for def foo(bar, baz)... foo = staticmethod(foo) Whereas # Deviant use; leaves function untouched @register def foo(bar, baz)... is shorthand for def foo(bar, baz)... register(foo) I am not claiming that it should be a common decorator idiom, only that I am comfortable with it and find it useful. By returning the original function, we could stack decorators so that multiple expressions could share the same parse action: @articleTitle.setParseAction @movieTitle.setParseAction @bookTitle.setParseAction def upcase_title(tokens): return .join( t.title() for t in tokens ) Here is where I have something of a hitch, with the way pyparsing implements most setXXX methods. setParseAction already returns a value, and the value returned is self. If you have any Smalltalk background, this will seem familiar to you. (Not that I was ever a big-time Smalltalk coder, but this was one language idiom that you learned on Day 0.5 or you were lost forever.) This makes it easy to chain together a constructor and multiple property setters into a single expression: timestamp = Regex(r\d\d(\/\d\d\){2} \d\d(:\d\d) {2}).setParseAction(convertTimeStamp).leaveWhitespace().setDebug() I am not a user of pyparsing (yet!), so my comment is completely uninformed, but I feel that what is gained in brevity by writing it like this, may be lost in clarity because separate notions are put together (parsing, processing, debugging). But if I understand correctly, I would be able to rewrite this as: # Grammar section timestamp = Regex(r\d\d(\/\d\d\){2} \d\d(:\d\d){2}) # Processing section timestamp.setParseAction(convertTimeStamp) timestamp.leaveWhitespace() # I'm not sure what this does! # Debugging section timestamp.setDebug() OK, now I understand what my problem is: - your existing setXXX methods mutate self and return it, thus breaking the quasi-rule that if you mutate something, don't return it (c.f. list.sort, etc); - your proposed 'decorator-friendly' setXXX methods mutate self and return their argument just to satisfy the decorator-friendliness constraint, but in spirit they return nothing. This is just a train of thought, and I hope that you won't take this the wrong way. I am arguing for the pleasure of it, and I am happy to lose the argument :) In the case where we have a single parse action shared by multiple expressions, we have to fall back to: def upcase_title(tokens): return .join( t.title() for t in tokens ) articleTitle.setParseAction(upcase_title) movieTitle.setParseAction(upcase_title) bookTitle.setParseAction(upcase_title) But, now that I've looked at this for a while, I may fall back on some other idioms: - just because you *can* do something doesn't mean you *should* do it - explicit is better than implicit You're (probably!) the best person to judge the syntactical balance of pyparsing! Decorator syntax is already a mysterious topic for many newbies, even when used for its normal application. Using a decorator to perform the same
Re: explain this function to me, lambda confusion
On May 9, 8:57 am, [EMAIL PROTECTED] wrote: On May 8, 6:11 pm, Duncan Booth [EMAIL PROTECTED] wrote: No, no, no, no, no! Geez. Go easy. You have got it entirely wrong here. Your XOR function simply returns a function which gives you the result of xoring the parameters AT THE TIME WHEN YOU ORIGINALLY CREATED IT. I'm guessing that you had already set cream and icecream (otherwise the call to XOR would have thrown an exception) and at leas one was true. Try setting them both False at the beginning: cream = False icecream = False topping = XOR( cream, icecream) cream = True icecream = False print topping() False Ok. I understand this better now. I did say I found the documentation rather terse on this. Using a lambda was a completely pointless exercise here, you could have just returned the result directly: If I try out a new language, I try to exercise those parts of the language that are new to me. Now I saw lambdas, an interesting structure I hadn't seen before. So I tried them out. I get to learn a little at the same time as scripting. That was the point. I only get to optimise my use of a language by trying out various corners of it. def TFF(x,y,z) : return x and not y and not z AddOnly = TFF( options.AddAction, options.ReplaceAction, options.DeleteAction ) DeleteOnly = TFF( options.DeleteAction, options.AddAction, options.ReplaceAction ) ReplaceOnly = TFF( options.ReplaceAction, options.AddAction, options.DeleteAction ) if not (DeleteOnly or AddOnly or ReplaceOnly): print Error: Exactly one of [ --add | --replace | --delete ] allowed. parser.print_help() exit which boils down to: if (options.AddAction + options.ReplaceAction + options.DeleteAction) != 1: print Error: ... Indeed, there are many ways this could be done. Some are more concise, some are more efficient. As I said, I did it the way I did it to try out lambdas. Your way achieves the result, rather elegantly I think, but teaches me nothing about using lambdas. Pardon my tetchiness, but it is a little hard to receive such blunt and inflexible replies to my posts. Both the responses offer lambda free alternatives. That's fine, and given the terse documentation and problems that I had understanding them, I would agree. So what applications are lambdas suited to? I think the parameterised function model is one. What else? Lambda can actually be safely removed from python and no other features would be missing. It is always possible to create a def version of any lambda, so lambda is useless. It is just a convenience for the times where we're just too lazy to invent a name and find a place to place the def, instead just inlining the function. -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
On May 9, 12:12 pm, Gabriel Genellina [EMAIL PROTECTED] wrote: En Thu, 08 May 2008 22:57:03 -0300, [EMAIL PROTECTED] escribió: On May 8, 6:11 pm, Duncan Booth [EMAIL PROTECTED] wrote: No, no, no, no, no! Geez. Go easy. You have got it entirely wrong here. Your XOR function simply [...] Pardon my tetchiness, but it is a little hard to receive such blunt and inflexible replies to my posts. Don't take it so seriously. I would have written a reply in the same tone. Weeds must be uprooted early :) Both the responses offer lambda free alternatives. That's fine, and given the terse documentation and problems that I had understanding them, I would agree. So what applications are lambdas suited to? I think the parameterised function model is one. What else? It should be clear now that lambda is just a shortcut for defining a normal function using def, except it has no name, and it can handle expressions only (no statements). So you never *need* a lambda. But in a few cases they're useful: - Most GUIs are event-driven, and let you bind a function (or any other callable object) to be executed when certain event happens (by example, when certain button is pressed, or a menu item is selected). Usually an instance method is used: Button(Total, onclick=self.calculate_total). Suppose you're developing a calculator; the ten buttons labeled '0' to '9' should inserte the corresponding digit. To do that, you should write ten functions insert_digit_0 to insert_digit_9 (and they would be one-line-functions: insert_digit('0') ... insert_digit('9')). Too boring :( The usual idiom is something like this: Button(0, onclick=lambda: self.insert_digit('0')) Button(5, onclick=lambda: self.insert_digit('5')) - To write an expression that is to be evaluated lazily (perhaps only if certain other conditions are met). Older Python versions didn't have a conditional expression like C's :? ternary operator, and one possible way to emulate it is this: def iif(cond, if_true, if_false): if cond: return if_true() else: return if_false() iff(x!=2, lambda: 1/(x-2), lambda: 100) You can't write iff(x!=2, 1/(x-2), 100) because arguments are evaluated before the function is called, and with x=2 you get an error. Calling iff would give a NameError. I wonder why... perhaps because iif is so iffy? -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
Lie [EMAIL PROTECTED] writes: Lambda can actually be safely removed from python and no other features would be missing. It is always possible to create a def version of any lambda, so lambda is useless. It is just a convenience for the times where we're just too lazy to invent a name and find a place to place the def, instead just inlining the function. Note that the same thing can be said about generator expressions, which are nothing more than anonymous, non-reusable, generator functions. Instead these were _added_ to the language! -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
Both the responses offer lambda free alternatives. That's fine, and given the terse documentation and problems that I had understanding them, I would agree. So what applications are lambdas suited to? I think the parameterised function model is one. What else? i've hardly ever used lambdas since map() and filter() were replaced by list comprehension. two other uses I can think of for it are: using it as a sorting key (which takes a function and lambdas are perfect for that when a direct function isn't available. for example, lambda x: x.myName), and I made an irc bot once that certain events had a list of fuctions that would be called after that event. it was like being able to dynamically add and remove event handlers. for example what if you asked the user a question and you wanted to know for the next input whether it was from that user and was an answer to that question. sometimes the function to add would be very simple, so writing a def for it would just be ugly. -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
Arnaud Delobelle [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] | Lie [EMAIL PROTECTED] writes: | | Lambda can actually be safely removed from python and no other | features would be missing. It is always possible to create a def | version of any lambda, so lambda is useless. It is just a convenience | for the times where we're just too lazy to invent a name and find a | place to place the def, instead just inlining the function. | | Note that the same thing can be said about generator expressions, | which are nothing more than anonymous, non-reusable, generator | functions. Right. So if someone posted on genexp confusion, I would suggest 'write a full generator function'. | Instead these were _added_ to the language! As a convenience. Actually, if one uses more that one for-clause in a generator expression, there is a potential gotcha in relation to name capture. So if that bites, the genexp is not so much a convenience, and one might better write the full function. tjr -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
[EMAIL PROTECTED] wrote: Indeed, there are many ways this could be done. Some are more concise, some are more efficient. As I said, I did it the way I did it to try out lambdas. Your way achieves the result, rather elegantly I think, but teaches me nothing about using lambdas. Unfortunately what you wrote taught you nothing about using lambda either. I think you were looking for it to have mystic powers, when in fact all it gives you is an alternative way to define a function. Pardon my tetchiness, but it is a little hard to receive such blunt and inflexible replies to my posts. It was blunt because your post was so wide of the mark, yet it was well written and at least at first glance sounded plausible. Other people had even followed up on minor points having apparently not spotted the bigger problem. Remember that what you post here is going to be archived by Google and instructing (or misleading) people for years to come so jumping hard on factual errors is (I think) worthwhile. (And I really appreciate it every time other people have jumped on things I've got wrong.) On the other hand, there are plenty of people who use lambda in situations which are more or less appropriate. Just how appropriate they are is usually a matter of opinion, and while I may express my opinion when I think they are misusing them, that's all it is: an opinion. Everyone is free to disagree (and generally does). -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
[EMAIL PROTECTED] wrote: Here is a simple lambda that implements an exclusive or: def XOR(x,y) : return lambda : ( ( x ) and not ( y ) ) or ( not ( x ) and ( y ) ) (Because of the resemblance to C macros, I have been cautious and written the lambda with lots of parentheses.) To use this in later code, we define instances of the lambda with specific function arguments. topping = XOR( cream, icecream) sauce = XOR( tomato, BBQ ) We now have two øfunctionsñ, topping() and sauce() which we can use later to test flags. cream = True icecream = False print topping() True No, no, no, no, no! You have got it entirely wrong here. Your XOR function simply returns a function which gives you the result of xoring the parameters AT THE TIME WHEN YOU ORIGINALLY CREATED IT. I'm guessing that you had already set cream and icecream (otherwise the call to XOR would have thrown an exception) and at leas one was true. Try setting them both False at the beginning: cream = False icecream = False topping = XOR( cream, icecream) cream = True icecream = False print topping() False Using a lambda was a completely pointless exercise here, you could have just returned the result directly: def XOR(x,y): return x^y topping = XOR(cream, icecream) print topping True Same thing for your TFF function: def TFF(x,y,z) : return x and not y and not z AddOnly = TFF( options.AddAction, options.ReplaceAction, options.DeleteAction ) DeleteOnly = TFF( options.DeleteAction, options.AddAction, options.ReplaceAction ) ReplaceOnly = TFF( options.ReplaceAction, options.AddAction, options.DeleteAction ) if not (DeleteOnly or AddOnly or ReplaceOnly): print Error: Exactly one of [ --add | --replace | --delete ] allowed. parser.print_help() exit which boils down to: if (options.AddAction + options.ReplaceAction + options.DeleteAction) != 1: print Error: ... -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
On May 8, 6:11 pm, Duncan Booth [EMAIL PROTECTED] wrote: No, no, no, no, no! Geez. Go easy. You have got it entirely wrong here. Your XOR function simply returns a function which gives you the result of xoring the parameters AT THE TIME WHEN YOU ORIGINALLY CREATED IT. I'm guessing that you had already set cream and icecream (otherwise the call to XOR would have thrown an exception) and at leas one was true. Try setting them both False at the beginning: cream = False icecream = False topping = XOR( cream, icecream) cream = True icecream = False print topping() False Ok. I understand this better now. I did say I found the documentation rather terse on this. Using a lambda was a completely pointless exercise here, you could have just returned the result directly: If I try out a new language, I try to exercise those parts of the language that are new to me. Now I saw lambdas, an interesting structure I hadn't seen before. So I tried them out. I get to learn a little at the same time as scripting. That was the point. I only get to optimise my use of a language by trying out various corners of it. def TFF(x,y,z) : return x and not y and not z AddOnly = TFF( options.AddAction, options.ReplaceAction, options.DeleteAction ) DeleteOnly = TFF( options.DeleteAction, options.AddAction, options.ReplaceAction ) ReplaceOnly = TFF( options.ReplaceAction, options.AddAction, options.DeleteAction ) if not (DeleteOnly or AddOnly or ReplaceOnly): print Error: Exactly one of [ --add | --replace | --delete ] allowed. parser.print_help() exit which boils down to: if (options.AddAction + options.ReplaceAction + options.DeleteAction) != 1: print Error: ... Indeed, there are many ways this could be done. Some are more concise, some are more efficient. As I said, I did it the way I did it to try out lambdas. Your way achieves the result, rather elegantly I think, but teaches me nothing about using lambdas. Pardon my tetchiness, but it is a little hard to receive such blunt and inflexible replies to my posts. Both the responses offer lambda free alternatives. That's fine, and given the terse documentation and problems that I had understanding them, I would agree. So what applications are lambdas suited to? I think the parameterised function model is one. What else? -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
En Thu, 08 May 2008 22:57:03 -0300, [EMAIL PROTECTED] escribió: On May 8, 6:11 pm, Duncan Booth [EMAIL PROTECTED] wrote: No, no, no, no, no! Geez. Go easy. You have got it entirely wrong here. Your XOR function simply [...] Pardon my tetchiness, but it is a little hard to receive such blunt and inflexible replies to my posts. Don't take it so seriously. I would have written a reply in the same tone. Weeds must be uprooted early :) Both the responses offer lambda free alternatives. That's fine, and given the terse documentation and problems that I had understanding them, I would agree. So what applications are lambdas suited to? I think the parameterised function model is one. What else? It should be clear now that lambda is just a shortcut for defining a normal function using def, except it has no name, and it can handle expressions only (no statements). So you never *need* a lambda. But in a few cases they're useful: - Most GUIs are event-driven, and let you bind a function (or any other callable object) to be executed when certain event happens (by example, when certain button is pressed, or a menu item is selected). Usually an instance method is used: Button(Total, onclick=self.calculate_total). Suppose you're developing a calculator; the ten buttons labeled '0' to '9' should inserte the corresponding digit. To do that, you should write ten functions insert_digit_0 to insert_digit_9 (and they would be one-line-functions: insert_digit('0') ... insert_digit('9')). Too boring :( The usual idiom is something like this: Button(0, onclick=lambda: self.insert_digit('0')) Button(5, onclick=lambda: self.insert_digit('5')) - To write an expression that is to be evaluated lazily (perhaps only if certain other conditions are met). Older Python versions didn't have a conditional expression like C's :? ternary operator, and one possible way to emulate it is this: def iif(cond, if_true, if_false): if cond: return if_true() else: return if_false() iff(x!=2, lambda: 1/(x-2), lambda: 100) You can't write iff(x!=2, 1/(x-2), 100) because arguments are evaluated before the function is called, and with x=2 you get an error. -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
explain this function to me, lambda confusion
i have a rough understanding of lambda but so far only have found use for it once(in tkinter when passing lambda as an argument i could circumvent some tricky stuff). what is the point of the following function? def addn(n): return lambda x,inc=n: x+inc if i do addn(5) it returns def addn(n): return lambda x,inc=n: x+inc addn(5) function lambda at 0x01D81830 ok? so what do i write to make it actually do something. and is the inc=n necessary i cant do x+n? -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
and what si the diffrence here: g = lambda x=5:x*x g = lambda x:x*x the first was a mistake to write but it worked and the x=5 seems to be completely ignored. why? it has no effect at all? -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
On 7 Maj, 23:47, globalrev [EMAIL PROTECTED] wrote: and what si the diffrence here: g = lambda x=5:x*x g = lambda x:x*x the first was a mistake to write but it worked and the x=5 seems to be completely ignored. why? it has no effect at all? ah wait now i see it has a default kind of then. g() returns 25 while g(8) returns 64. -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
On 7 mai, 23:38, globalrev [EMAIL PROTECTED] wrote: i have a rough understanding of lambda but so far only have found use for it once(in tkinter when passing lambda as an argument i could circumvent some tricky stuff). what is the point of the following function? def addn(n): return lambda x,inc=n: x+inc It returns a function that accept one argument and return the result of the addition of this argument with the argument passed to addn. FWIW, Python's lambda is just a shortcut to create a very simple function, and the above code is canonically written as: def makeadder(n): def adder(x): return n + x return adder if i do addn(5) it returns (snip) function lambda at 0x01D81830 ok? so what do i write to make it actually do something. add5 = addn(5) add5(1) = 6 add5(2) = 7 add42 = addn(42) add42(1) = 43 and is the inc=n necessary i cant do x+n? In this case, it's not. This version does exactly the same thing AFAICT: def addn(n): return lambda x: x+n -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
En Wed, 07 May 2008 18:38:15 -0300, globalrev [EMAIL PROTECTED] escribió: i have a rough understanding of lambda but so far only have found use for it once(in tkinter when passing lambda as an argument i could circumvent some tricky stuff). what is the point of the following function? def addn(n): return lambda x,inc=n: x+inc lambda is just a shortcut for defining a function without a name. The above code is the same as: def addn(n): def inner(x, inc=n): return x+inc return inner It should be clear now that addn returns a function. addn is a function factory: builds functions by request. You ask it give me a function that adds 5 and addn returns that function. if i do addn(5) it returns addn(5) function lambda at 0x01D81830 If you try the other version, you would get: function inner at 0x00A3B970 It's the same thing, except that lambda has no name. ok? so what do i write to make it actually do something. adder5 = addn(5) adder5(3) - 8 and is the inc=n necessary i cant do x+n? Yes, you can, but there is a subtle difference that's hard to explain, and in this case it's absolutely irrelevant. Using inc=n does the right thing as it's a bit more efficient too. -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
On May 8, 7:38 am, globalrev [EMAIL PROTECTED] wrote: i have a rough understanding of lambda but so far only have found use for it once(in tkinter when passing lambda as an argument i could circumvent some tricky stuff). what is the point of the following function? def addn(n): return lambda x,inc=n: x+inc if i do addn(5) it returns def addn(n): return lambda x,inc=n: x+inc addn(5) function lambda at 0x01D81830 ok? so what do i write to make it actually do something. and is the inc=n necessary i cant do x+n? Here are some notes I have written for our local wiki on lambdas in python. I hope you will find them illuminating, and I would welcome any suggestions for improving them. I have just cut and pasted from our wiki, so the fancy formatting has been lost. - Python lambdas. The on-line documentation for python lambdas is not very illuminating. Here’s my take and my first simple examples. I would describe a lambda as a parameterised function template. If you dig, the docs call lambdas anonymous functions not bound to a name. There is a bit of resemblance to C macros. Here is a simple lambda that implements an exclusive or: def XOR(x,y) : return lambda : ( ( x ) and not ( y ) ) or ( not ( x ) and ( y ) ) (Because of the resemblance to C macros, I have been cautious and written the lambda with lots of parentheses.) To use this in later code, we define instances of the lambda with specific function arguments. topping = XOR( cream, icecream) sauce = XOR( tomato, BBQ ) We now have two “functions”, topping() and sauce() which we can use later to test flags. cream = True icecream = False print topping() True So in the definition of the XOR lambda, think of x and y as the parameters of the function template, and XOR as the function name placeholder. By putting in specific objects for the parameters (here the boolean variables cream and icecream for example), we produce a specific instance of the lambda, topping() which looks like a function with no arguments. If we use different objects for the parameters (say tomato and BBQ) then we get a different function, sauce. Here is another simple lambda, (template) to set up three new functions AddOnly, DeleteOnly, and ReplaceOnly. #--# Lambda function to check that a flag is only on when the other two are off. #--# def TFF(x,y,z) : return lambda : ( ( x ) and not ( y ) and not ( z ) ) AddOnly = TFF( options.AddAction, options.ReplaceAction, options.DeleteAction ) DeleteOnly = TFF( options.DeleteAction, options.AddAction, options.ReplaceAction ) ReplaceOnly = TFF( options.ReplaceAction, options.AddAction, options.DeleteAction ) if( not (DeleteOnly() or AddOnly() or ReplaceOnly() ) ): print Error: Exactly one of [ --add | --replace | --delete ] allowed. parser.print_help() exit More advanced lambdas. The examples above give function instances that have no arguments, once the parameters of the lambda are chosen. For a function template with arguments and parameters, we add the arguments on the 2nd line. Parameters are in the first line. The Gaussian distribution is exp(-(x-μ)²/ 2σ² ) / √(4 πσ). While we can think of this as a function of three variables, we normally view it as a family of functions of a single variable x, parameterised by μ and σ. Selecting fixed values for μ and σ gives us a single distribution for x. import math def Gaussian( mu, sigma ) : ... return lambda x : math.exp( - (x-mu)**2 / 2 /sigma**2 ) / math.sqrt (2 * math.pi *sigma **2 ) ... and here are some instances: Normal = Gaussian (0, 1) HeightDistrib = (170, 20) which we later use as y = Normal( 0.5 ) 0.35206532676429952 x = 192 HeightDistrib(x) 0.0073381331586869951 I recommend defining the instances of the lambda right after the lambda. If you define it in code far removed from the definition of the lambda, it looks like an assignment, so comment it. -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
On May 8, 10:34 am, [EMAIL PROTECTED] wrote: HeightDistrib = (170, 20) That should be HeightDistrib = Gaussian(170, 20) -- http://mail.python.org/mailman/listinfo/python-list
Re: explain this function to me, lambda confusion
[EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] | On May 8, 7:38 am, globalrev [EMAIL PROTECTED] wrote: | I would describe a lambda as a parameterised function template. If you | dig, the docs call lambdas anonymous functions not bound to a name. A lambda expression is an abbreviation of a simple def statement: f = lambda args: expression def f(args): return expression have exactly the same effect except that f.func_name will be the less useful 'lambda' instead of the more useful 'f'. | There is a bit of resemblance to C macros. Macros in C (and, I believe, some places elsewhere) are text-replacement templates. They are markedly different from function statements. C macros do not create C functions. Python lambda expression do create Python function objects. Since C macros are statements, not expressions, and are introduced by #define, similar to def, one could argue than Python def statements are more similar to C macros. | Here is a simple lambda that implements an exclusive or: | | def XOR(x,y) : |return lambda : ( ( x ) and not ( y ) ) or ( not ( x ) and ( y ) ) def XORY(x,y): def _xory(): x and not y or not x and y return _xory has the same effect. Because lambda expressions define functions, not macros, there is no need for the protective parentheses that macros need. Here is another simple lambda, (template) to set up three new | functions AddOnly, DeleteOnly, and ReplaceOnly. | | #--# Lambda function to check that a flag is only on when the other | two are off. #--# | def TFF(x,y,z) : | return lambda : ( ( x ) and not ( y ) and not ( z ) ) def TFF(x,y,z): def _tff(x,y,z): return ( ( x ) and not ( y ) and not ( z ) ) return _tff Same result (except for a real name in tracebacks), same usage. | import math | def Gaussian( mu, sigma ) : | ... return lambda x : math.exp( - (x-mu)**2 / 2 /sigma**2 ) / | math.sqrt (2 * math.pi *sigma **2 ) def Gaussian(mu, sigma): def _gaussian(x): return math.exp( - (x-mu)**2 / 2 /sigma**2 ) / math.sqrt (2 * math.pi *sigma **2 ) return _gaussian Again, giving the returned function a name will help a bit if it raises an exception, which is definitely possible here. Lambda expressions are an occasional convienience, not a requirement. Anyone who is confused by what they do should use an equivalent def instead. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list