2009-06-23 13 views

Respuesta

16

No hay una construida en pero no es a fuerza de rodar es el propietario:

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

ya que "[b] ooleans son un subtipo de la llanura enteros "(source) puede sumar la lista de enteros con bastante facilidad y también puede pasar verdaderos booleanos en esta función.

Así pues, estas dos llamadas son homogéneos:

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

Si quieren conversión explícita booleano: sum(bool(x) for x in args) == 1.

+0

Me gusta esto - ¿Quizás pueda actualizarlo para convertir los args a bools explícitamente? –

+2

Creo que quieres escribir '' sum (bool (a) para a en args) == 1'' - las variables mismas pueden no ser booleanas. – elo80ka

+0

Me encantan los one-liners. Acabo de aprender algo nuevo sobre bools. – 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 pregunta a la que se vinculó ya proporciona la solución para dos variables. Todo lo que tiene que hacer es extender para trabajar en n variables:

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

Como de costumbre, reducir es un amigo falso: esto realmente comprueba si hay un número ODD de valores verdaderos: ¡será tan feliz con 7 o 77 como con solo 1! –

+0

Tienes razón ... aunque creo que la culpa sería más de mi lógica defectuosa que 'reducir '. Gracias por mencionarlo. – elo80ka

1

Aquí es mi enfoque directo. Lo renombré solo_una vez porque xor con más de una entrada suele ser un corrector de paridad, no un inspector "solo uno".

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

Pruebas:

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

creo que la solución basada en la suma está muy bien para el ejemplo dado, pero hay que tener en cuenta que los predicados booleano en Python siempre cortocircuito su evaluación. Por lo que es posible que desee considerar algo más consistente con all and any.

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

Agradable. Debería explicar que el 'no any (it)' funciona en el resto de los elementos que dejan el 'any (it)', para las personas que no se sienten cómodas con los iteradores. – tzot

+0

Aquí hay una discusión sobre este uso: http://stackoverflow.com/a/16801605/4403872, y aquí: http://stackoverflow.com/a/16522290/4403872 – vk1011

Cuestiones relacionadas