Tags

, , , ,


Recently a friend of mine asked me if there was a ternary operator in Python and it got me thinking.

Languagues such as C even have a syntax like [[ condition ? ifblock : thenblock ]]

The first thought that came to mind was using Dictionaries and lambda functions. A dictionary can also use the Boolean type for true so:-

{‘True’: lambda x : ifblockfunction(), ‘False’: lambda x : elseblockfunction()}[condition]()

So basically its a dictionary lookup agaist the condition that returns the apprpriate lambda function. Since lambda’s are functions, the () at the end is that of a function call.

Okay you guys still with me, cos I have more to tell you.

I learned python over a year ago back in the days of 2.4 and a notation that I hadnt come across that exists from 2.5 onwards is the [[ ifblock if cond else elseblock ]].

>>>5 if False else 7

Should return 7.

Pretty nifty I’d say, resembles what its parse tree would look like.

If you’re using python 2.4 or below, you must be quite disappointed by now but theres more, however you’ll have to bear with me on this one.

In python, datatypes inside an if statement evaluate to True or False. So if(3) should give True[Note not actual language syntax]. Similarly if([1,3,4]), if ((1,3,4)), etc all return True.

So what returns false. None, False, empty lists, empty tuples, etc return false

This is a functionality that Python could have inherited LISP since in LISP everystatement evaluates to something.

1234 and True

The above line should evaluate to True which it does. But consider this

>>> True and 1234
1234
>>> 1234 and True
True

True and 1234 evaluates to 1234, so its returning the second True Element and it doesnt make a differece because essentially both True and 1234 are True

So how can we use this to our liking. Consider the following.

“T” and condition or “F”

This would return “T” for True and “F” for false by shortcircuit evaluation.

However func1() and True or func2() wont work.

Function calls return None to the language and func1() would be executed anyways during the inorder execution so it would be of no use to us.

Therefore in order to make this work we can once again resort to lambda functions as follows:-

>>>(lambda : mojo()) and False or (lambda : len(“sdf”))()
3

This is the geekiest solution by far and it has the same inorder tree placement as its syntax in 2.5

P.S. I love language related information. If anyone found this useful and has anything to share, gems left in the comments section for me to munch on shall highly be appreciated.

Advertisements