Есть ли встроенная функциональная версия `and` и/или` or` в Python?
Этот вопрос для удовольствия; Я не ожидаю, что ответ будет полезен.
Когда я вижу, что люди делают вещи с reduce()
в Python, они часто используют встроенную функцию в Python, часто из модуля operator
.
Это работает:
result = reduce(lambda a, b: a + b, range(5))
Но обычно вы увидите следующее:
from operator import add
result = reduce(add, range(5))
Что странно для меня, что модуль operator
, похоже, не имеет функции для логического and
. Он имеет побитовое и, но не логическое and
.
Предположим, вы это делаете:
result = reduce(lambda a, b: a and b, range(1, 6))
Есть ли встроенная функция, которая может быть использована здесь?
Мне также интересно, есть ли встроенная функция, которая может заменить or
.
Если вы сначала сопоставляете аргументы с Booleans, вы можете использовать побитовое и от operator
или просто использовать bool.__and__
, например:
from operator import and_
result = reduce(and_, map(bool, range(1, 6)))
result = reduce(bool.__and__, map(bool, range(1, 6)))
И аналогично с operator.or_()
или bool.__or__
для операции or
. Но я ищу функцию, которая не нуждается в значениях, сопоставленных с Booleans.
Если бы вы знали наверняка, что ваши значения являются целыми числами, вы можете использовать operator.mul
для and
и operator.add
для or
. Это было бы грубым взломом, и я не хочу этого ответа... особенно учитывая, насколько дорого будут умножаться, если бы встретилось много чисел, и ни один из них не был равен нулю!
Примечание. Я знаю all()
и any()
, которые являются лучшими заменами для этого использования reduce()
. Как я сказал наверху, я прошу это для удовольствия.
Примечание. Функция, которая имеет побочный эффект форсирования всех значений до bool
, будет приемлемым ответом. Встроенное ключевое слово and
не делает этого:
x = 3 and 5 # sets x to 5, not to True
Но для этого вопроса меня интересует только функция, которая может работать с reduce()
для выполнения логических операций and
или or
.
Ответы
Ответ 1
Я предполагаю, что фактическая причина, по которой в модуле оператора нет and
и or
, заключается в невозможности оценивать аргументы функции в режиме короткого замыкания - это вся точка булевых операторов. Таким образом, ответ на ваш вопрос - нет, нет встроенной функции, которая может имитировать and/or
, и не возможно написать ее.
all/any
, применяемые к генераторам, также имеют короткое замыкание
def gen():
yield 1
yield this_wont_be_evaluated
print any(gen())
но я не знаю, как заставить эту работу работать с аргументами времени выполнения
Ответ 2
Нет встроенных функций, которые я знаю, что делаю это. Однако вы можете определить тривиальные функции, которые обертываются вокруг операторов:
>>> 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
Ответ 3
Примечание. Функция, которая имеет побочный эффект, заставляя все значения bool будет приемлемым ответом. Встроенный и ключевое слово не сделайте это
но встроенное ключевое слово not
делает.
In : not 255
Out: False
In : not 0
Out: True
конечно, вам нужно будет вернуть свою логику назад, а затем:
In : not (not 5 and not 0) # mimics: 5 or 0
Out: True
поэтому с этим можно эмулировать all()
через reduce
, map
и 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
- это то, что вы хотели достичь? Боюсь, мы не сможем приблизиться.