[Tutor] Use of "or" in a lambda expression

Steven D'Aprano steve at pearwood.info
Sun Apr 5 05:32:08 CEST 2015


On Sun, Apr 05, 2015 at 12:55:16AM +0100, Alan Gauld wrote:
> On 04/04/15 22:57, boB Stepp wrote:
> >On Sat, Apr 4, 2015 at 3:35 PM, Alan Gauld <alan.gauld at btinternet.com> 
> >wrote:
> >>He could have done it in various other ways too:
> >>
> >>eg.
> >>lambda : all(print('Hello lambda world!'), sys.exit() )
> >
> >Is this what you meant? Because print will always return False. Or did
> >you actually mean:
> >
> >lambda: any(print('Hello lambda world!'), sys.exit())
> 
> any() would be more obvious, but in my interpreter
> both any() and all() evaluate both functions before
> testing the results. At least they do once you
> fix the TypeError : they should be in a list/tuple...
> 
> lambda : all([print('Hello lambda world!'), sys.exit()] )


That's because the sys.exit() call leaves the interpreter because any() 
gets a chance to raise TypeError :-) Your code:

lambda: all(print('Hello lambda world!'), sys.exit())

is equivalent to this:

a = print('Hello lambda world!')
b = sys.exit()  # Goodbye cruel world!
all(a, b)  # this never gets called


so you could replace the call to all() with any(), or len(), or 
zxcvbnm() if you like, it makes no difference at all.

The moral equivalent of the original `or` trick would be something like 
this:

any(spam() for spam in [lambda: print("Hello lambda world!"), os.exit])

which now avoids calling os.exit until necessary. E.g. we might write a 
function which prints a message, then has a 50% chance of exiting:


any(spam() for spam in [lambda: print("Hello lambda world!"), 
                        lambda: random.random() > 0.5,
                        lambda: print("Goodbye cruel world!"),
                        os.exit]
                        )

will always print Hello, and fifty percent of the time will print 
Goodbye then exit, otherwise it will return True.


-- 
Steve


More information about the Tutor mailing list