Estou lutando para encontrar uma maneira mais limpa de retornar um valor booleano se meu conjunto estiver vazio no final da minha função
Eu considero a interseção de dois conjuntos e desejo retornar True
ou com False
base no fato de o conjunto resultante estar vazio.
def myfunc(a,b):
c = a.intersection(b)
#...return boolean here
Meu pensamento inicial foi fazer
return c is not None
No entanto, no meu intérprete, posso ver facilmente que a declaração retornará verdadeira se c = set([])
>>> c = set([])
>>> c is not None
True
Também tentei todos os seguintes:
>>> c == None
False
>>> c == False
False
>>> c is None
False
Agora eu li a partir da documentação que eu só posso usar and
, or
e not
com conjunto vazio para deduzir um valor booleano. Até agora, a única coisa que posso pensar é retornar, não c
>>> not not c
False
>>> not c
True
Tenho a sensação de que existe uma maneira muito mais pythônica de fazer isso, pois estou lutando para encontrá-la. Não quero retornar o conjunto real para uma instrução if porque não preciso dos valores, só quero saber se eles se cruzam.
bool(set([]))
isdisjoint
. Estou completamente chocado.Respostas:
def myfunc(a,b): c = a.intersection(b) return bool(c)
bool()
fará algo semelhantenot not
, mas mais ideomático e claro.fonte
bool(...)
quando você está perguntandois_empty
é obscuro. Eu não expresso a intenção.not not
;). (FTR: Eu já votei positivamente na resposta de @gefeis, mas não tenho influência sobre o que o OP aceitou ...)não tão pítônico quanto as outras respostas, mas matemática:
return len(c) == 0
Como alguns comentários questionaram sobre o impacto que
len(set)
poderia ter na complexidade. É O (1) conforme mostrado no código-fonte, visto que depende de uma variável que rastreia o uso do conjunto.static Py_ssize_t set_len(PyObject *so) { return ((PySetObject *)so)->used; }
fonte
len(c)
mesmo sec
for muito grande, o que é desnecessário para verificar se há vazio.set()
(python 3.5.2 no Windows)Se você quiser
return True
para um conjunto vazio, então acho que seria mais claro fazer:return c == set()
ou seja, "
c
é igual a um vazioset
".(Ou, ao contrário,
return c != set()
).Em minha opinião, isso é mais explícito (embora menos idiomático) do que confiar na interpretação do Python de um conjunto vazio como
False
em um contexto booleano.fonte
Se
c
é um conjunto, então você pode verificar se ele está vazio, fazendo:return not c
.Se
c
estiver vazio, entãonot c
estaráTrue
.Caso contrário, se
c
contiver algum elementonot c
seráFalse
.fonte
Quando voce diz:
c is not None
Na verdade, você está verificando se c e None fazem referência ao mesmo objeto. Isso é o que o operador "é" faz. Em python, Nenhum é um valor nulo especial convencionalmente, o que significa que você não tem um valor disponível. Sorta como null em c ou java. Uma vez que o python atribui internamente apenas um valor None usando o operador "is" para verificar se algo é None (pense nulo) funciona, e se tornou o estilo popular. No entanto, isso não tem a ver com o valor verdade do conjunto c, é verificar se c realmente é um conjunto e não um valor nulo.
Se você quiser verificar se um conjunto está vazio em uma instrução condicional, ele é convertido como um booleano no contexto para que você possa apenas dizer:
c = set() if c: print "it has stuff in it" else: print "it is empty"
Mas se quiser que seja convertido em booleano para ser armazenado, você pode simplesmente dizer:
c = set() c_has_stuff_in_it = bool(c)
fonte
""" 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()
fonte
Não tão limpo quanto o bool (c), mas era uma desculpa para usar o ternário.
def myfunc(a,b): return True if a.intersection(b) else False
Também usando um pouco da mesma lógica, não há necessidade de atribuir a c, a menos que você o esteja usando para outra coisa.
def myfunc(a,b): return bool(a.intersection(b))
Por fim, suponho que você deseja um valor True / False porque irá realizar algum tipo de teste booleano com ele. Eu recomendaria pular a sobrecarga de uma chamada de função e definição, simplesmente testando onde for necessário.
Ao invés de:
if (myfunc(a,b)): # Do something
Talvez isto:
if a.intersection(b): # Do something
fonte