Python has a syntax to mimic ternary operator, but its syntax is like inverted as the if result is written before the if. Writing if else for a ternary operator makes other languages to look smarter, as they have a ? and : syntax instead. My proposal is to have a python function called ternary.
# current way Python does ternary condition: myvar = 7 if a == 0 else 8 # Do you think it is a bit ugly syntax?
My proposal - which I am already using with no issues, is Python to have a ternary function
Your version doesnât short circuit the evaluation of whichever value doesnât get used (value_if_true and value_if_false are both evaluated). So you couldnât do something like ternary(a is None, None, a.foo). So itâs not a replacement.
If you find your code useful, you can put it in your own library. But it wonât be added to Python.
At least you have conceded that your first estimate was wrong by a factor of one Thousand. But, you are still wrong by much more than another factor of one Thousand.
(Edit:) But, obviously, you know how important short-circuiting can be, since you have added a try-except-block to your proposal after the fact. However, that change does not fix the issues that have been brought up. The code ternary(a is None, None, a.foo) would still throw an exception.
One which, to my knowledge, can never actually catch anything. OP, please donât make substantive edits like this; an unacknowledged change to the essence of your post makes it difficult to reply usefully, and also difficult to follow the thread afterwards (you canât know which version of the proposal someone was responding to). Instead, post a followup to suggest the alternative, so that it is itself a post that can easily be replied to.
I actually quite like the resulting call, personally:
myvar = ternary(a == 0, 7, 8)
But the implementation above is a long way from being ready from builtins
Why on earth should a ternary function or operator, suppress all Exceptions and return a custom on_exception arg (or None)? Instead of either just letting it fail, or logging the exception and reraising it (e.g. except Exception as e: logger.error(e); raise e)? This isnât close to a proper Maybe Monad pattern (itâs not how Go handles errors is it)?
The stated goal is to replace an if block or an existing Python âternaryâ, with myvar = ternary(a == 0, 7, 8). But to use this safely, or with normal Exception propagation, Iâve got to wrap it in its own entire extra if block to test if it returns on_exception or not. If Iâve got to always use the same common pattern to call a helper function, I would argue that boilerplate should live inside the helper function (or at least, another one).
Ah right, forgot about that. So I guess that makes the OPâs updated function an example, not of a termary function, but of ternary logic: âhere is a value, if itâs truthy return this, if itâs falsy return that, if it isnât boolable return the thirdâ.
Whatâs true of waterfowl is true of functions like this: One good tern deserves another.
OP, youâre editing the post again instead of posting followups. Please stop. Reply to the thread if you want to say something different.
Argument order was a large part of the prolonged ternary conditional expression discussion. The C order was favored by many, but Guido picked what he ultimately did. The latter works better than many, including me, expected.
The current conditional expression replaced condition and expression or default, which has a subtle flaw that I no longer remember (and do not wish to). Many uses of the replaced compound expression depended on short-circuiting, so the replacement needed to do the same. The general pattern is expression if computing_expression_will not raise else default, where default is a constant or expression that cannot fail. I suspect that this includes more that 1% of uses.
Itâs always a pleasure to learn you core devs are way ahead of me. And in this case not only that, from a look at PEP308 you were so, over 20 years ago.
Anyway, one flaw in and / or is if expression 1 is Falsey, it evaluates to expression 2 regardless of the value of the condition.
If condition was truthy but expression was falsely it would go on to evaluate default, which a proper ternary operator would not do (short-circuiting is vital).
So, as a joke, I posted this to use instead:
(condition and [expression] or [default])[0]
But too many people took that to heart, and started using that absurdity in their code. As I recall, neither Guido nor I thought Python âneededâ a ternary operator at the time, but the spread of the idiom was too ugly to bear.
So Guido reluctantly gave in to an unreasoning mob ,
Thank you Tim. ânot neededâ in the sense that nearly always one of expession1 or expression2 could not be falsey and if both could be, an explicit if-else statement was available. But as I remember, a) a and b or c was mentioned in a FAQ and b) someone reported a negative experience with a hard-to-notice falsey bug. I now freely use what I once thought unbearably ugly. I suggest OP and others also try to adjust.
Having used it for many years, I now find val1 if cond else val2 to be minorly ugly, but not unbearably so. The fact that itâs evaluated from the middle out, instead of left to right as with Câs style, is a downside. Not a deal-breaker but it does force a re-reading in complex expressions (imagine if the condition is seldom true, and you see that the beginning of an expression will bomb - you have to go further than it to find that thereâs actually a conditional check on it).
assumes that the only bad thing that can happen when both value_if_true and value_if_false are evaluated, is an exception. But this is not true, short circuiting is essential:
def backup(filename):
... Make a backup of the file
return f"{filename} backed up"
def delete(filename)
... Delete the file
return f"{filename} deleted"
def is_garbage(filename):
... Return whether the filename is garbage (and should be deleted) or not (and should be backed up)
print(delete(filename) if is_garbage(filename) else backup(filename))