25

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
Cory Klein
  • 51,188
  • 43
  • 183
  • 243
  • 2
    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.) – user2357112 Dec 13 '18 at 00:08

4 Answers4

47

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

Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • YES I could not find anywhere that "elvis operator" was mentioned, but this is functionally equivalent. Thank you. – Cory Klein Feb 15 '18 at 17:33
  • And I've never heard of "elvis operator" before. – Robᵩ Feb 15 '18 at 17:34
  • 12
    If you interpret `?:` as a smiley, the curl of the question mark resembles Elvis' emblematic hairstyle. – FeepingCreature Nov 29 '18 at 08:34
  • 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()`. – Cromax Sep 19 '21 at 00:02
  • @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, https://en.m.wikipedia.org/wiki/Elvis_operator – Robᵩ Sep 19 '21 at 22:20
  • @Robᵩ Heck, you're right, I had this wrong all the time. :-) – Cromax Sep 20 '21 at 11:14
  • 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) – lem0nify Feb 28 '23 at 03:19
  • @lem0nify - you seem to be describing the [null-coalescing operator](https://en.wikipedia.org/wiki/Null_coalescing_operator), which has the behavior you list. On the other hand, the [Elvis operator](https://en.wikipedia.org/wiki/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. – Robᵩ Mar 01 '23 at 21:06
12

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

Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99
  • 1
    OP specifically asked about checking `a` for truthiness, not checking `a is not None`. – CrazyChucky Dec 27 '20 at 16:50
  • 1
    @CrazyChucky 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. – Aleksandr Dubinsky Dec 27 '20 at 17:23
  • 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? – CrazyChucky Dec 27 '20 at 17:25
  • 1
    @CrazyChucky 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"](https://en.wikipedia.org/wiki/Elvis_operator#Object_reference_variant) and in examples has entries for '??' as well. So the term is not exactly clear-cut. – Aleksandr Dubinsky Dec 27 '20 at 17:36
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.

markusk
  • 6,477
  • 34
  • 39
-3
>>> 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
Blessed Geek
  • 21,058
  • 23
  • 106
  • 176