Как применить логический оператор ко всем элементам в списке python
У меня есть список булевых в python. Я хочу И (ИЛИ ИЛИ ИЛИ НЕ) их и получить результат. Следующий код работает, но не очень pythonic.
def apply_and(alist):
if len(alist) > 1:
return alist[0] and apply_and(alist[1:])
else:
return alist[0]
Любые предложения о том, как сделать его более pythonic оцененным.
Ответы
Ответ 1
Логический and
для всех элементов в a_list
:
all(a_list)
Логический or
для всех элементов в a_list
:
any(a_list)
Если вы чувствуете себя творчески, вы также можете:
import operator
def my_all(a_list):
return reduce(operator.and_, a_list, True)
def my_any(a_list):
return reduce(operator.or_, a_list, False)
имейте в виду, что они не оцениваются в коротком замыкании, а встроенные -; -)
еще один смешной способ:
def my_all_v2(a_list):
return len(filter(None,a_list)) == len(a_list)
def my_any_v2(a_list):
return len(filter(None,a_list)) > 0
и еще один:
def my_all_v3(a_list):
for i in a_list:
if not i:
return False
return True
def my_any_v3(a_list):
for i in a_list:
if i:
return True
return False
и мы могли бы продолжать весь день, но да, пифонический способ - использовать all
и any
: -)
Кстати, у Python нет исключения рекурсии хвоста, поэтому не пытайтесь перевести код LISP непосредственно; -)
Ответ 2
AND и ORing просты:
>>> some_list = [True] * 100
# OR
>>> any(some_list)
True
#AND
>>> all(some_list)
True
>>> some_list[0] = False
>>> any(some_list)
True
>>> all(some_list)
False
Замечание также довольно легко:
>>> [not x for x in some_list]
[True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
Конечно, как вы могли бы использовать эти результаты, могут потребоваться некоторые интересные приложения теоремы ДеМоргана.
Ответ 3
Уменьшить может сделать это:
reduce(lambda a,b: a and b, alist, True)
Как сказано выше, все это самый краткий способ сделать это. Но уменьшите ответы на более общий вопрос: "Как применить логический оператор ко всем элементам в списке python?"
Ответ 4
Идиомой для таких операций является использование функции reduce
(глобальная в Python 2.X, в модуле functools
в Python 3.X) с соответствующим бинарным оператором, взятым из модуля operator
или закодированным в явном виде. В вашем случае это operator.and_
reduce(operator.and_, [True, True, False])
Ответ 5
Здесь другое решение:
def my_and(a_list):
return not (False in a_list)
def my_or(a_list):
return True in a_list
ИСПОЛЬЗОВАНИЕ всех элементов вернет True, если все элементы True, следовательно, False в списке.
ORing аналогичен, но он должен возвращать True, если хотя бы одно True значение присутствует в списке.
Ответ 6
Как показывают другие ответы, есть несколько способов выполнить эту задачу. Здесь другое решение, которое использует функции из стандартной библиотеки:
from functools import partial
apply_and = all
apply_or = any
apply_not = partial(map, lambda x: not x)
if __name__ == "__main__":
ls = [True, True, False, True, False, True]
print "Original: ", ls
print "and: ", apply_and(ls)
print "or: ", apply_or(ls)
print "not: ", apply_not(ls)