Toskan
Toskan

Reputation: 14931

Python's equivalent to PHP's null coalesce operator and shorthand ternary operator?

I was looking here and couldn't find anything: https://docs.python.org/3/library/operator.html

Two examples of PHP that come in handy a lot:

echo $count ?: 10; //prints $count if $count is not empty string, null, false or 0, otherwise prints 10.

echo $a ?? $b ?? 7; //prints $a if $a is defined and not null, otherwise will print $b, otherwise 7

Are there equivalent operators in Python? Note:

a if condition else b

does not really replace the shorthand ternary operator, because condition and return value are specified in one element in PHP in the shorthand version.

Upvotes: 9

Views: 5970

Answers (3)

thomasrutter
thomasrutter

Reputation: 117343

This is really two different questions because the examples work differently.

Example 1

This one has a much simpler solution.

$count ?: 10

Python equivalent to this would be:

count or 10

Explanation: in PHP the ?: operator returns the value of the right value if the first value is false-like, like || or or does in some other dynamic languages.

Example 2

$a ?? $b ?? 7

The difficulty of achieving this in Python is that in PHP, $a and/or $b are allowed to be undefined, in which case the value returned is $b - or 7 if both are undefined.

Essentially, the ?? operator in PHP is a stand-in for isset() in a ternery expression, and isset() also has that special property of allowing the variable to be undefined.

One thing that makes this more achievable by PHP is that variables have to be prepended with a dollar sign - that way, the parser can know that an unrecognized identifier was intended to be a variable name that hasn't been declared yet.

A close Python equivalent to this would be:

a if a is not None else b if b is not None else 7

This is about as close as you can get in one statement. However, because there's nested ternery statements in it, it's a bit inelegant because it's a bit hard to read. It will also fail if either a or b hasn't been declared yet, unlike the PHP equivalent. If you need to support that scenario, then you will have to rewrite other code.

Generally, it is bad practice in Python (not to mention difficult to achieve) to write code where you are using a variable that may not have been declared yet, and the code should be written so you don't encounter this situation.

Alternative situation

It wasn't specified in the question, but let's say the reason you don't know if a value is defined or not is that it's an entry in a dict (PHP equivalent of associative array).

That is, let's say a is item['someoption'] and b is item['someotheroption']

In this case dict.get() comes in handy because you can specify a fallback value if the dict has no item with that key. That is, you can use item.get('someoption', 7) to fall back to 7 if 'someoption' doesn't exist as a key in item (and if you don't give a second argument, the fallback will be None).

And if you want to check both at once like in the example you could use

item.get('someoption', item.get('someotheroption', 7))

Technically, if other of those values are None you may still end up with a result of None instead of 7. If you want the fallback to occur when either value is None or doesn't exist in the dict, you could do:

result = item.get('someoption', item.get('someotheroption'))
return result if result is not None else 7

And you could combine the above into a single line if you wanted, but readability would probably suffer further.

Upvotes: 0

Trolldejo
Trolldejo

Reputation: 466

In Python there is a way to do ternary operations:

print((b, a)[a])  # if a: prints a; otherwise prints b

Explanation

The options are in a tuple : (b, a) the [condition] will determine either we call element at rank 0 (condition is false) or 1 in the tuple (condition is true).

Examples

a = False
b = "youpi"
print((b, a)[a])
# youpi

condition = "Thirsty"
print(("Foo" , "Bar")[condition == "Thirsty"])
# Bar

Upvotes: -2

Adam S
Adam S

Reputation: 444

The or operator returns the first truth-y value.

a = 0
b = None
c = 'yep'

print(a or 'nope')
print(b or 'nope')
print(c or 'nope')
print(b or c or 'nope')
> nope
> nope
> yep
> yep

Upvotes: 11

Related Questions