2009-06-23 9 views

Odpowiedz

16

Nie ma jeden wbudowany ale nie jest ciężko toczyć jesteś właścicielem:

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

ponieważ „[b] ooleans są podtypem zwykły liczby całkowite "(source) można łatwo zliczyć listę liczb całkowitych i można również przekazać prawdziwe booleany do tej funkcji.

Więc te dwa połączenia są jednorodne:

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

Jeśli chcesz wyraźny logiczną konwersję: sum(bool(x) for x in args) == 1.

+0

Podoba mi się to - może możesz go zaktualizować, aby przekonwertować args na bools? –

+2

Myślę, że masz na myśli napisać '' sum (bool (a) dla a in args) == 1'' - same zmienne mogą nie być wartościami logicznymi. – elo80ka

+0

Po prostu kocham jedno-liniowce. Właśnie nauczyłem się czegoś nowego o boolach. – Deon

3
>>> 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

Pytanie, z którym już się łączyłeś, zapewnia rozwiązanie dla dwóch zmiennych. Wszystko, co musisz zrobić, to rozszerzyć go do pracy na n zmiennych:

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 
+1

Jak zwykle, zmniejsz jest fałszywym przyjacielem: to faktycznie sprawdza, czy istnieje liczba ODD prawdziwych wartości - będzie tak samo szczęśliwa z 7 lub 77, jak z zaledwie 1! –

+0

Masz rację ... chociaż sądzę, że wina byłaby większa w mojej błędnej logice niż "zredukować". Dziękuję za wskazanie. – elo80ka

1

Oto moje proste podejście. Zmieniono jego nazwę only_one, ponieważ xor z więcej niż jednym wejściem jest zazwyczaj kontrolerem parzystości, a nie kontrolerem "tylko jeden".

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

Testowanie:

>>> 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 
7

Myślę, że rozwiązanie oparte suma jest w porządku podanym przykładzie, ale należy pamiętać, że Boolean predykaty w Pythonie zawsze zwierać ich oceny. Więc możesz rozważyć coś bardziej zgodnego z all and any.

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

Nice. Powinieneś wyjaśnić, że 'not any (it)' działa na reszcie rzeczy pozostawionych przez 'any (it)', dla osób, które nie są wygodne z iteratorami. – tzot

+0

Istnieje zdrowa dyskusja na temat tego użycia tutaj: http://stackoverflow.com/a/16801605/4403872, a tutaj: http://stackoverflow.com/a/16522290/4403872 – vk1011

Powiązane problemy