Есть ли встроенная функциональная версия `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

- это то, что вы хотели достичь? Боюсь, мы не сможем приблизиться.