19

変数のリスト内の 1 つの変数だけが True 値を持っているかどうかを確認する簡単な方法を探しています。私はこの論理的な xor の投稿を見て、複数の変数に適応する方法を見つけようとしていますが、1 つだけが 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

「[bo]oleans は単純な整数のサブタイプです」( source ) ため、整数のリストを簡単に合計でき、真のブール値をこの関数に渡すこともできます。

したがって、これら 2 つの呼び出しは同種です。

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

明示的なブール変換が必要な場合: sum( bool(x) for x in args ) == 1.

于 2009-06-23T13:02:34.580 に答える
9

与えられた例では合計ベースのソリューションで問題ないと思いますが、Pythonのブール述語は常に評価を短絡させることに注意してください。したがって、すべておよびすべてとより一貫性のあるものを検討することをお勧めします。

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

リンクした質問は、すでに 2 つの変数の解決策を提供しています。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

これが私の率直なアプローチです。複数の入力を持つ xor は通常、「1 つだけ」のチェッカーではなく、パリティ チェッカーであるため、名前を only_one に変更しました。

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 に答える