如何将逻辑运算符应用于python列表中的所有元素


89

我在python中有一个布尔值列表。我想对它们进行AND(或OR或NOT)操作并获得结果。下面的代码可以工作,但不是非常Pythonic。

def apply_and(alist):
 if len(alist) > 1:
     return alist[0] and apply_and(alist[1:])
 else:
     return alist[0]

任何有关如何使其更pythonic的建议表示赞赏。

Answers:


175

逻辑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

并且我们可以整天去,但是是的,pythonic方法是使用alland any:-)

顺便说一句,Python还没有消除尾递归,所以不要尝试直接翻译LISP代码;-)


8
operator.and_是按位与运算符&,而不是逻辑与。
蚂蚁阿斯玛09年

1
不幸的是,True和False(根据操作需要)分别转换为1和0,因此按位运算符用作逻辑^ _ ^
fortran

6
解释了很多冗余版本,但未提供实际正确答案的语法。
jwg

2
不同意您想要的任何内容,它位于常见问题解答中:stackoverflow.com/privileges/vote-down
fortran

2
请注意,这reduce()functools因为Python 3.0
Duncan WP

33

ANDing和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]

当然,如何使用这些结果可能需要DeMorgan定理的一些有趣应用。


4
如果要对not变体进行短循环,只需使用生成器表达式:(all(not x for x in some_list)但这与not any(some_list)(相当自然的表达式,是吗?)相同)。
u0b34a0f6ae

16

减少可以做到这一点:

reduce(lambda a,b: a and b, alist, True)

如fortran所述,一切都是最简洁的方法。但是减少回答一个更笼统的问题:“如何将逻辑运算符应用于python列表中的所有元素?”


4
减少不会消失,AFAIK。它已从其在全局名称空间中的先前位置移至functools模块中
Eli Bendersky,2009年

1
@eliben:为什么在将来时谈论Python 3?减少仍然存在reducefunctools.reduce 在Python 3
u0b34a0f6ae

如果您删除了, True,则对于非布尔值列表,此答案将是实际上与问题代码等效的唯一答案。
托马斯·阿勒

10

这种操作的惯用法是将reduce函数(在Python 2.X中为全局,functools在Python 3.X中为模块)与适当的二进制运算符一起使用,该运算符取自operator模块或显式编码。就你而言operator.and_

reduce(operator.and_, [True, True, False])

4

这是另一个解决方案:

def my_and(a_list):
    return not (False in a_list)

def my_or(a_list):
    return True in a_list

如果所有元素均为True,则所有元素的AND运算将返回True,因此列表中没有False。ORing类似,但如果列表中至少存在一个True值,则应返回True。


0

如其他答案所示,有多种方法可以完成此任务。这是另一个使用标准库中函数的解决方案:

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.