2009-06-23 11 views

risposta

16

non ce n'è uno costruito in ma non è a duro a rotolare si possiede:

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

Dal momento che "[b] ooleans sono un sottotipo di pianura interi "(source) è possibile sommare abbastanza facilmente l'elenco degli interi e passare anche i veri booleani in questa funzione.

Quindi queste due chiamate sono omogenei:

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

Se si desidera esplicita di conversione booleano: sum(bool(x) for x in args) == 1.

+0

Mi piace questo, forse è possibile aggiornarlo per convertire gli argomenti in bool esplicitamente? –

+2

Penso che intendi scrivere '' sum (bool (a) per a in args) == 1'' - le variabili stesse potrebbero non essere booleane. – elo80ka

+0

Adoro i one-liner. Ho appena imparato qualcosa di nuovo sui bool. – 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

La domanda a cui è collegato fornisce già la soluzione per due variabili. Tutto ciò che devi fare è estenderlo per lavorare su n variabili:

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

Come al solito, ridurre è un falso amico: questo in realtà controlla se c'è un numero ODD di valori veri - sarà altrettanto felice con 7 o 77 quelli come con solo 1! –

+0

Hai ragione ... anche se immagino che la colpa sarebbe più sulla mia logica difettosa che su "ridurre". Grazie per segnalarlo. – elo80ka

1

Ecco il mio approccio diretto. L'ho rinominato solo_solo poiché xor con più di un input è solitamente un correttore di parità, non un controllore "solo uno".

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

Testing:

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

Penso che la soluzione sum-based è bene per l'esempio dato, ma di tenere presente che booleano predicati in python sempre corto circuito la loro valutazione. Quindi potresti voler considerare qualcosa di più coerente con all and any.

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

Bello. Dovresti spiegare che il 'not any (it)' funziona sul resto degli elementi lasciati da 'any (it)', per le persone che non sono a loro agio con gli iteratori. – tzot

+0

Ecco una sana discussione di questo utilizzo qui: http://stackoverflow.com/a/16801605/4403872, e qui: http://stackoverflow.com/a/16522290/4403872 – vk1011

Problemi correlati