简体   繁体   中英

Is there a builtin function version of `and` and/or `or` in Python?

This question is for fun; I don't expect the answer to be useful.

When I see people doing things with reduce() in Python, they often take advantage of a builtin function in Python, often from the operator module.

This works:

result = reduce(lambda a, b: a + b, range(5))

But usually you would see this:

from operator import add
result = reduce(add, range(5))

What's strange to me is that the operator module doesn't seem to have a function for logical and . It does have bitwise and, but not logical and .

So suppose you are doing this:

result = reduce(lambda a, b: a and b, range(1, 6))

Is there a builtin function that can be used here?

I'm also wondering if there is a builtin function that can replace or .

If you map the arguments to Booleans first, you can use the bitwise and from operator , or just directly use bool.__and__ , like so:

from operator import and_
result = reduce(and_, map(bool, range(1, 6)))
result = reduce(bool.__and__, map(bool, range(1, 6)))

And likewise with operator.or_() or bool.__or__ for the or operation. But I am looking for a function that doesn't need the values mapped to Booleans.

If you knew for certain that your values are all integers, you could use operator.mul for and and operator.add for or . This would be a crude hack and I don't want this answer... especially considering how expensive the multiplications would get if many numbers were encountered and none of them were zero!

Note: I am aware of all() and any() , which are better replacements for this use of reduce() . As I said at the top, I'm asking this for fun.

Note: A function that has the side-effect of forcing all values to bool would be an acceptable answer. The built-in and keyword doesn't do this:

x = 3 and 5  # sets x to 5, not to True

But for the purpose of this question I am just interested in a function that can work with reduce() to do logical and or or operations.

I guess the actual reason why there's no and and or in the operator module is that it's impossible to evaluate function arguments in a short-circuit fashion - which is the whole point of boolean operators. So the answer to your question is no, there's no built-in function that can mimic and/or nor is it possible to write one.

all/any applied to generators are short-circuiting as well

def gen():
    yield 1
    yield this_wont_be_evaluated

print any(gen())

but I have no idea how make that work with run-time arguments

There are no builtin functions I'm aware of that do this. However, you can define trivial functions that wrap around the operators:

>>> def newand(a,b):
...  return a and b
...
>>> def newor(a,b):
...  return a or b
...
>>> reduce(newand, map(bool, range(5))) # Will return False, because bool(0) == False
False
>>> reduce(newand, map(bool, range(1,5))) # Now 0 is excluded
True

Note: A function that has the side-effect of forcing all values to bool would be an acceptable answer. The built-in and keyword doesn't do this

but the built-in not keyword does.

In : not 255
Out: False

In : not 0
Out: True

of course, you'll have to get your logic backwards, then:

In : not (not 5 and not 0) # mimics: 5 or 0
Out: True

so, with this you can emulate all() via reduce , map , and operator.* :

In : not reduce(operator.or_,map(operator.not_,[1,2,3,4,5])) # mimics all(1,2,3,4,5)
Out: True

In : not reduce(operator.or_,map(operator.not_,[1,2,3,0,5])) # mimics all(1,2,3,0,5)
Out: False

is that (sort of) what you wanted to achieve? I'm afraid we cannot get any closer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM