19

我正在寻找一种简单的方法来检查变量列表中是否只有一个变量具有 True 值。我已经查看了这个逻辑异或帖子,并试图找到一种方法来适应多个变量并且只有一个是真的。

例子

>>>TrueXor(1,0,0)
True

>>>TrueXor(0,0,1)
True

>>>TrueXor(1,1,0)
False

>>>TrueXor(0,0,0,0,0)
False
4

5 回答 5

23

没有内置的,但不难让你拥有:

def TrueXor(*args):
    return sum(args) == 1

由于“[b]ooleans 是纯整数的子类型”(source),你可以很容易地对整数列表求和,你也可以将真正的布尔值传递给这个函数。

所以这两个调用是同质的:

TrueXor(1, 0, 0)
TrueXor(True, False, False)

如果你想要显式的布尔转换:sum( bool(x) for x in args ) == 1.

于 2009-06-23T13:02:34.580 回答
9

我认为基于总和的解决方案对于给定的示例来说很好,但请记住,python 中的布尔谓词总是会使它们的评估短路。因此,您可能需要考虑与all 和 any更一致的东西。

def any_one(iterable):
    it = iter(iterable)
    return any(it) and not any(it)
于 2009-06-23T15:07:06.640 回答
5
>>> def f(*n):
...     n = [bool(i) for i in n]
...     return n.count(True) == 1
...
>>> f(0, 0, 0)
False
>>> f(1, 0, 0)
True
>>> f(1, 0, 1)
False
>>> f(1, 1, 1)
False
>>> f(0, 1, 0)
True
>>>
于 2009-06-23T13:02:33.503 回答
1

您链接到的问题已经为两个变量提供了解决方案。您所要做的就是扩展它以处理 n 个变量:

import operator

def only_one_set(*vars):
    bools = [bool(v) for v in vars]
    return reduce(operator.xor, bools, False)

>>> a, b, c, d, e = False, '', [], 10, -99
>>> only_one_set(a, b, c, d)
True
>>> only_one_set(a, b, c, d, e)
False
于 2009-06-23T13:08:36.223 回答
1

这是我的直截了当的方法。我已将其重命名为 only_one,因为具有多个输入的 xor 通常是奇偶校验检查器,而不是“唯一一个”检查器。

def only_one(*args):
    result = False
    for a in args:
        if a:
            if result:
                return False
            else:
                result = True
    return result

测试:

>>> only_one(1,0,0)
True
>>> only_one(0,0,1)
True
>>> only_one(1,1,0)
False
>>> only_one(0,0,0,0,0)
False
>>> only_one(1,1,0,1)
False
于 2009-06-23T13:10:10.027 回答