Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compressing `x if x else y` statement in Python

I'm quite acquainted with Python's ternary operator approach:

value = foo if something else bar 

My question is very simple: without prior assignments, is there anyway to reference the term being evaluated in (if ...) from one of the return operands (... if or else ...)?

The motivation here is that sometimes I use expressions in if ... that are exactly what I'd like to have as result in the ternary operation; happens though that, for small expressions, there's no problem repeating it, but for a bit longer expressions, it goes somewhat nasty. Take this as an example:

value = info.findNext("b") if info.findNext("b") else "Oompa Loompa" 
like image 789
Rubens Avatar asked Dec 31 '12 19:12

Rubens


People also ask

How do you write if and else in one line in Python?

Writing a one-line if-else statement in Python is possible by using the ternary operator, also known as the conditional expression. This works just fine. But you can get the job done by writing the if-else statement as a neat one-liner expression.

What is then in Python?

Python does not use the word THEN but uses a colon instead.

Can we use in IF statement in Python?

Python Nested if statementsWe can have a if... elif...else statement inside another if... elif...else statement. This is called nesting in computer programming.


1 Answers

There is no way to do this, and that's intentional. The ternary if is only supposed to be used for trivial cases.

If you want to use the result of a computation twice, put it in a temporary variable:

value = info.findNext("b") value = value if value else "Oompa Loompa" 

Once you do this, it becomes clear that you're doing something silly, and in fact the pythonic way to write this is:

value = info.findNext("b") if not value:     value = "Oompa Loompa" 

And that's actually 5 fewer keystrokes than your original attempt.

If you really want to save keystrokes, you can instead do this:

value = info.findNext("b") or "Oompa Loompa" 

But that's discouraged by many style guides, and by the BDFL.

If you're only doing this once, it's better to be more explicit. If you're doing it half a dozen times, it's trivial—and much better—to make findNext take an optional default to return instead of None, just like all those built-in and stdlib functions:

def findNext(self, needle, defvalue=None):     # same code as before, but instead of return None or falling off the end,     # just return defvalue. 

Then you can do this:

value = info.findNext("b", "Oompa Loompa") 
like image 60
abarnert Avatar answered Oct 07 '22 18:10

abarnert