On the operator
module, we have the or_
function, which is the bitwise or (|
).
However I can't seem to find the logical or (or
).
The documentation doesn't seem to list it.
I'm wondering why isn't it included? Is it not considered a operator?
Is there a builtin function that provides its behaviour?
The or
operator short circuits; the right-hand expression is not evaluated when the left-hand returns a true value. This applies to the and
operator as well; when the left-hand side expression returns a false value, the right-hand expression is not evaluated.
You could not do this with a function; all operands have to be evaluated before the function can be called. As such, there is no equivalent function for it in the operator
module.
Compare:
foo = None
result = foo and foo(bar)
with
foo = None
result = operator.boolean_and(foo, foo(bar)) # hypothetical and implementation
The latter expression will fail, because you cannot use None
as a callable. The first version works, because the and
operator won't evaluate the foo(bar)
expression.
The closest thing to a built-in or
function is any:
>>> any((1, 2))
True
If you wanted to duplicate or
's functionality of returning non-boolean operands, you could use next with a filter:
>>> next(operand for operand in (1, 2) if operand)
1
But like Martijn said, neither are true drop-in replacements for or
because it short-circuits. A true or
function would have to accept functions to be able to avoid evaluating all the results:
logical_or(lambda: 1, lambda: 2)
This is somewhat unwieldy, and would be inconsistent with the rest of the operator
module, so it's probably best that it's left out and you use other explicit methods instead.
This can explicitly be found in the docs:
The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
It does not exist as an operator
function because due to the language specification, it is impossible to implement because you cannot delay execution of a called argument when calling the function. Here is an example of or
in action:
def foo():
return 'foo'
def bar():
raise RuntimeError
If bar is called, we get a Runtime error. And looking at the following line, we see that Python shortcuts the evaluation of the line, since foo
returns a True
-ish value.
>>> foo() or bar()
'foo'
We can simulate this behavior by passing in uncalled functions, and then calling them inside our or
function:
def my_or(*funcs):
for func in funcs:
call = func()
if call:
return call
return call
>>> my_or(foo, bar)
'foo'
But you cannot shortcut execution of called callables that are passed to a function:
>>> my_or(foo, bar())
Traceback (most recent call last):
File "<pyshell#28>", line 1, in <module>
like_or(foo, bar())
File "<pyshell#24>", line 2, in bar
raise RuntimeError
RuntimeError
So it would be improper to include such a function in the built-ins or standard library because users would expect an or
function to work just as a boolean or
test, which again, is impossible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With