Проверьте, установлена ​​ли только одна переменная в списке переменных - PullRequest
12 голосов
/ 23 июня 2009

Я ищу простой способ проверить, имеет ли Истинное значение только одна переменная в списке переменных. Я посмотрел этот логический xor пост и пытаюсь найти способ адаптироваться к нескольким переменным и только к одной истинной.

Пример

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

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

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

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

Ответы [ 5 ]

19 голосов
/ 23 июня 2009

Там нет ни одного встроенного, но это не трудно свернуть себя:

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.

7 голосов
/ 23 июня 2009

Я думаю, что решение на основе суммы подходит для данного примера, но имейте в виду, что логические предикаты в python всегда замыкают свою оценку. Так что вы можете рассмотреть что-то более совместимое с all и любым .

def any_one(iterable):
    it = iter(iterable)
    return any(it) and not any(it)
3 голосов
/ 23 июня 2009
>>> 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
>>>
1 голос
/ 23 июня 2009

Вот мой простой подход. Я переименовал его 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
1 голос
/ 23 июня 2009

Вопрос, с которым вы связались, уже дает решение для двух переменных. Все, что вам нужно сделать, это расширить его для работы с 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
...