【问题标题】:How to perform logical operations OR on list [multiple elements]?如何在列表[多个元素]上执行逻辑运算或?
【发布时间】:2016-12-20 07:43:31
【问题描述】:

有没有办法比较列表元素并返回结果值? 下面是python sn-p,它接收两个值并返回值。

def logical_or_decision(a,b):
    return a or b

value = logical_or_decision(1,0)
print value

我需要使其通用且可扩展到超过 2 个元素。我怎样才能为超过 2 个元素做到这一点?

【问题讨论】:

  • 您要严格返回TrueFalse,还是(在or 的情况下)列表的第一个真值,如a or b or c or ... 那样?

标签: python list logical-operators any


【解决方案1】:

有一个内置函数可以做到这一点:any

>>> any([0,0,1,0])
True

>>> any([0,0,0])
False

【讨论】:

  • 和“和”等价的all
  • 如果有 3 个像 0,1,-1 这样的元素怎么办?假设我有一个 [0,-1] 列表,它应该返回-1。如果 [0,0,-1] ,它应该返回 -1
  • @Jackie -1 代表什么?您还使用了哪些其他输入?
  • 不,只有三个输入。我的意思是代表三种可能的状态,成功、失败和未知。 0, 1, -1
  • @Jackie 这根本不是问题所说的。提出一个包含所有信息的新问题;编辑这个会使 5 个答案无效。包括一些示例输入/输出 - 您期望函数为某些给定输入返回什么。
【解决方案2】:

最佳解决方案^^以上^^:

any([True, False, True])
# returns True

any 很好,因为“短路”(如“布尔快速评估”它不会迭代到最后)。

如果您想要类似但手动且急切的东西 - 请参阅reduce

from operator import or_
from functools import reduce

reduce(or_, [True, False, True])
# returns True

【讨论】:

  • any() 不是懒惰,它只是短路。它的惰性取决于你作为参数传递给它的可迭代对象。
  • 是的,你说的很对。我的意思是 any 在“生成器惰性评估”和“布尔快速评估”方面是“惰性的”——首先停止 True 元素——它直到最后都不会迭代。
  • 没错,但正确的说法是短路。懒惰是你会与例如生成器相关的东西,它们可以暂停它们的执行,并根据需要将结果返回给你,而不是一次全部返回。这里any() 不知道传递给它的项目,它只是一个一个地迭代它。因此,它完全取决于传递给它的可迭代对象。
【解决方案3】:

你可以使用reduce来做:

def logical_or_decision(*args):
    return reduce(
        lambda a, b: a or b,
        args,
        False
    )

print logical_or_decision(1, 1, 1, 0) # False

当然您可以使用anyall(用于逻辑AND),但reduce 可以为您提供构建此类操作的一般方法(不适用于ORAND)。

【讨论】:

  • 您可能希望将它与operator module 中可用的运算符一起使用,而不是使用lambda
  • @AshwiniChaudhary 请注意,operator.or_|,而不是 or
  • @tobias_k 哎呀!我的错。
【解决方案4】:

内置函数any() 是解决此问题的正确方法:

def logical_or_decision(*args):
    return any(args)

value = logical_or_decision(1, 0, 0, 1, 0, 0) 
print value

以上官方文档链接中的相关部分:

如果可迭代的任何元素为真,则返回 True。如果可迭代对象为空,则返回 False。相当于:

def any(iterable):
   for element in iterable:
       if element:
           return True
   return False

【讨论】:

    【解决方案5】:

    这个问题有两种可能的解释:

    1。可迭代的所有元素的 OR & AND 操作:

    或: any

    与: all

    l1 = [True, False, False, True]
    t1 = (True, True, True)
    t2 = (False, False, False, False)
    
    any(l1)  # True
    all(l1)  # False
    any(t1)  # True
    all(t1)  # True
    any(t2)  # False
    all(t2)  # False
    

    2。多个对的 OR & AND 操作作为两个可迭代对象:

    在这种情况下使用的函数是相同的,但是你需要使用 map 和 zip 函数来包装它们:

    l = [True, True, False]
    t = (True, False, False)
    
    list(map(any, zip(l, t)))   # [True, True, False]
    tuple(map(all, zip(l, t)))  # (True, False, False)
    

    注意:我已经使用列表和元组来证明它可以使用不同的类似数组的结构来完成。第二个示例中的列表和元组包装器是 Python3,因为 map 返回的是迭代器而不是列表,这将给出非人类可读的答案。

    【讨论】:

      【解决方案6】:

      来自您的comment

      假设我有一个 [0,-1] 列表,它应该返回 -1。如果 [0,0,-1] ,它应该返回 -1

      虽然大多数人建议使用 anyall,但这似乎不是您真正想要的:

      >>> lst1 = [0, False, [], -1, ""]
      >>> lst2 = [4, True, "", 0]
      >>> any(lst1)
      True
      >>> all(lst2)
      False
      

      相反,您可以将reduce 内置函数(或在Python 3 中:functools.reduce)与一致的lambda 函数一起使用,将orand 应用于操作数,以获得第一个@987654325 @列表中的值:

      >>> reduce(lambda a, b: a or b, lst1)
      -1
      >>> reduce(lambda a, b: a and b, lst2)
      ''
      

      另外,operator.or_and_ 将不起作用,因为它们是按位的 |& 而不是逻辑的 orand

      >>> reduce(operator.or_, lst1)
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: unsupported operand type(s) for |: 'int' and 'list'
      >>> lst = [1, 2, 4]
      >>> reduce(operator.or_, lst)
      7
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-02
        • 2021-08-05
        • 2016-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多