关于python:检查变量列表中是否只设置了一个变量

Check if only one variable in a list of variables is set

我正在寻找一个简单的方法来检查变量列表中是否只有一个变量具有真值。我看过这篇逻辑XOR文章,并试图找到一种方法来适应多个变量,而只有一个是真的。

例子

1
2
3
4
5
6
7
8
9
10
11
>>>TrueXor(1,0,0)
True

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

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

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

没有一个内置的,但它不难滚动你自己:

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

由于"[b]ooleans是普通整数的子类型"(source),您可以很容易地求和整数列表,也可以将真正的布尔值传递给此函数。

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

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

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


我认为对于给定的例子,基于和的解决方案是可以的,但是请记住,python中的布尔谓词总是会缩短它们的计算。所以你可能想考虑一些更符合所有人和任何人的东西。

1
2
3
def any_one(iterable):
    it = iter(iterable)
    return any(it) and not any(it)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> 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
>>>

这是我的直截了当的方法。我只重命名了它,因为具有多个输入的XOR通常是一个奇偶校验,而不是一个"唯一"校验。

1
2
3
4
5
6
7
8
9
def only_one(*args):
    result = False
    for a in args:
        if a:
            if result:
                return False
            else:
                result = True
    return result

测试:

1
2
3
4
5
6
7
8
9
10
>>> 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

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

1
2
3
4
5
6
7
8
9
10
11
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