Estoy luchando por encontrar una forma más limpia de devolver un valor booleano si mi conjunto está vacío al final de mi función
Tomo la intersección de dos conjuntos y quiero regresar True
o False
basándome en si el conjunto resultante está vacío.
def myfunc(a,b):
c = a.intersection(b)
#...return boolean here
Mi pensamiento inicial fue hacer
return c is not None
Sin embargo, en mi intérprete puedo ver fácilmente que la afirmación volverá verdadera si c = set([])
>>> c = set([])
>>> c is not None
True
También probé todo lo siguiente:
>>> c == None
False
>>> c == False
False
>>> c is None
False
Ahora que he leído de la documentación que solo puedo usar and
, or
y not
con conjuntos vacíos para deducir un valor booleano. Hasta ahora, lo único que se me ocurre es regresar, no no c
>>> not not c
False
>>> not c
True
Tengo la sensación de que hay una forma mucho más pitónica de hacer esto, ya que estoy luchando por encontrarla. No quiero devolver el conjunto real a una declaración if porque no necesito los valores, solo quiero saber si se cruzan.
bool(set([]))
isdisjoint
. Estoy completamente sorprendido.Respuestas:
def myfunc(a,b): c = a.intersection(b) return bool(c)
bool()
Hará algo similarnot not
, pero más ideomático y claro.fuente
bool(...)
cuando lo preguntasis_empty
es oscuro. No expreso la intención.not not
;). (FTR: Ya había votado a favor de la respuesta de @gefeis, pero no tengo influencia en lo que OP aceptó ...)no tan pitónico como las otras respuestas, sino matemáticas:
return len(c) == 0
Como algunos comentarios se preguntaron sobre el impacto que
len(set)
podría tener en la complejidad. Es O (1) como se muestra en el código fuente dado que se basa en una variable que rastrea el uso del conjunto.static Py_ssize_t set_len(PyObject *so) { return ((PySetObject *)so)->used; }
fuente
len(c)
incluso sic
es muy grande, lo cual es innecesario para verificar el vacío.set()
(Python 3.5.2 en Windows)Si lo desea
return True
para un conjunto vacío, creo que sería más claro hacerlo:return c == set()
es decir, "
c
es igual a un vacíoset
".(O, al revés,
return c != set()
).En mi opinión, esto es más explícito (aunque menos idiomático) que confiar en la interpretación de Python de un conjunto vacío como
False
en un contexto booleano.fuente
Si
c
es un conjunto continuación, puede comprobar si está vacío haciendo:return not c
.Si
c
está vacío, entoncesnot c
lo estaráTrue
.De lo contrario, si
c
contiene algún elementonot c
seráFalse
.fuente
Cuando tu dices:
c is not None
En realidad, está comprobando si cy None hacen referencia al mismo objeto. Eso es lo que hace el operador "is". En Python, None es un valor nulo especial, lo que significa convencionalmente que no tiene un valor disponible. Sorta como nulo en c o java. Dado que Python internamente solo asigna un valor Ninguno usando el operador "es" para verificar si algo es Ninguno (creo que nulo) funciona, y se ha convertido en el estilo popular. Sin embargo, esto no tiene que ver con el valor de verdad del conjunto c, está comprobando que c en realidad es un conjunto en lugar de un valor nulo.
Si desea verificar si un conjunto está vacío en una declaración condicional, se convierte en un booleano en contexto, por lo que puede decir:
c = set() if c: print "it has stuff in it" else: print "it is empty"
Pero si desea que se convierta en un booleano para que se almacene, simplemente puede decir:
fuente
""" This function check if set is empty or not. >>> c = set([]) >>> set_is_empty(c) True :param some_set: set to check if he empty or not. :return True if empty, False otherwise. """ def set_is_empty(some_set): return some_set == set()
fuente
No tan limpio como bool (c) pero fue una excusa para usar ternary.
def myfunc(a,b): return True if a.intersection(b) else False
Además, utilizando un poco de la misma lógica, no es necesario asignar ac a menos que lo esté utilizando para otra cosa.
def myfunc(a,b): return bool(a.intersection(b))
Finalmente, supongo que desea un valor Verdadero / Falso porque va a realizar algún tipo de prueba booleana con él. Recomendaría omitir la sobrecarga de una llamada y definición de función simplemente probando donde lo necesite.
En vez de:
if (myfunc(a,b)): # Do something
Tal vez esto:
if a.intersection(b): # Do something
fuente