Does Python have the Elvis operator?
Asked Answered
F

4

27

The ternary operator in many languages works like so:

x = f() ? f() : g()

Where if f() is truthy then x is assigned the value of f(), otherwise it is assigned the value of g(). However, some languages have a more succinct elvis operator that is functionally equivalent:

x = f() ?: g()

In python, the ternary operator is expressed like so:

x = f() if f() else g()

But does python have the more succinct elvis operator?

Maybe something like:

x = f() else g() # Not actually valid python
Flattie answered 15/2, 2018 at 17:31 Comment(1)
Undoing the dupe-close because this is not asking for null-coalescing behavior. (Also, the accepted answer on the old dupe target is bug-prone and terrible.)Flexion
D
50

Yes

Python does have the elvis operator. It is the conditional or operator:

x = f() or g()

f() is evaluated. If truthy, then x is assigned the value of f(), else x is assigned the value of g().

Reference: https://en.wikipedia.org/wiki/Elvis_operator#Analogous_use_of_the_short-circuiting_OR_operator

Dorso answered 15/2, 2018 at 17:32 Comment(8)
YES I could not find anywhere that "elvis operator" was mentioned, but this is functionally equivalent. Thank you.Flattie
And I've never heard of "elvis operator" before.Transfiguration
If you interpret ?: as a smiley, the curl of the question mark resembles Elvis' emblematic hairstyle.Brunhild
This is not equivalent of Elvis operator, which is ternary operator while or is binary operator. Meaning: you can't decide if call f() or g() depending on some other condition h().Marysa
@Cromax, you seem to be conflating the Elvis operator (a ?: b) with the ternary operator (c ? a : b). They are not the same thing. See, for example, en.m.wikipedia.org/wiki/Elvis_operatorTransfiguration
@Dorso Heck, you're right, I had this wrong all the time. :-)Marysa
There is a problem with or operator: it returns the right expression even if the left one is not None but equals to 0. The purpose of elvis operator is to perform strict null/nil/undefined/None checks. Every language has logical OR operator but some of them also provide elvis operator or alternative (like ?? in JS)Grecism
@Grecism - you seem to be describing the null-coalescing operator, which has the behavior you list. On the other hand, the Elvis operator is based on truthiness, not existence. Regardless, OP is clearly asking for a truthiness operator. or describes perfectly what the OP is looking for.Transfiguration
Y
14

NB Python does not have the null-coalescing operator defined by:

a if a is not None else b

The or operator in a or b checks the truthiness of a which is False when a==0 or len(a)==0 or other similar situations. See What is Truthy and Falsy

There is a proposal to add such operators PEP 505

Yeargain answered 27/12, 2020 at 16:38 Comment(4)
OP specifically asked about checking a for truthiness, not checking a is not None.Pound
@Pound Hmm, I may have fudged the distinction between the elvis operator and the null-coalescing operator. Nevertheless I'll leave this answer up for others who may have the same confusion.Yeargain
Good point, I think it's worth pointing out. Perhaps mention specifically that the Elvis and null-coalescing operator are similar, but have this distinction?Pound
@Pound Edited. I'll point out that some languages, like Kotlin, use ?: for null-coallescing and Wikipedia actually has sections for both behaviors under "elvis operator" and in examples has entries for '??' as well. So the term is not exactly clear-cut.Yeargain
S
0

Robᵩ's answer about using or is a good suggestion. However, as a comment to the original question,

x = f() ? f() : g()

is functionally equivalent with

x = f() ?: g()

only if f() has no side effects.

If, for instance, f() reads from a stream or generator, calling it twice will have different results than calling it once. Rewriting slightly to Python syntax, the following sample

values = (x for x in (1, 2, 3))
def f(): return next(values)
def g(): return 42
x = f() if f() else g()
print(x)

will print 2, while x = f() or g() would print 1.

It might be better to state the question as

tmp = f()
x = tmp ? tmp : g()

or, in Python,

tmp = f()
x = tmp if tmp else g()

or in Python 3.8 and up,

x = tmp if (tmp := f()) else g()

Both of the latter two examples are equivalent with

x = f() or g()

regardless of any side effects f() might have.

Sinasinai answered 10/1, 2022 at 9:29 Comment(0)
C
-2
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4]
>>> a + (b,c)[b>c]
[1, 2, 3, 4]
>>> a + (b,c)[b<c]
[1, 2, 3, 4, 5, 6]
>>> 

Python elvis operation is

(testIsFalse, testIsTrue)[test]

The Java equivalent is

test ? testIsTrue:testIsFalse
Coimbra answered 11/3, 2020 at 5:48 Comment(1)
That's not what the elvis operator does. You're thinking of the ternary operator.Yeargain

© 2022 - 2024 — McMap. All rights reserved.