Staram się znaleźć bardziej czysty sposób zwracania wartości logicznej, jeśli mój zestaw jest pusty na końcu mojej funkcji
Biorę przecięcie dwóch zestawów i chcę zwrócić True
lub False
na podstawie tego, czy wynikowy zestaw jest pusty.
def myfunc(a,b):
c = a.intersection(b)
#...return boolean here
Moja pierwsza myśl była taka
return c is not None
Jednak w moim tłumaczu z łatwością widzę, że stwierdzenie zwróci prawdę, jeśli c = set([])
>>> c = set([])
>>> c is not None
True
Wypróbowałem również wszystkie z poniższych:
>>> c == None
False
>>> c == False
False
>>> c is None
False
Teraz już odczytać z dokumentacji, że można używać tylko and
, or
i not
ze zbiór pusty wydedukować wartość logiczną. Jak dotąd jedyne, co mogę wymyślić, to powrót nie c
>>> not not c
False
>>> not c
True
Mam wrażenie, że istnieje znacznie bardziej pytoniczny sposób, aby to zrobić, ponieważ staram się go znaleźć. Nie chcę zwracać rzeczywistego zestawu do instrukcji if, ponieważ nie potrzebuję wartości, chcę tylko wiedzieć, czy się przecinają.
bool(set([]))
isdisjoint
. Jestem całkowicie w szoku.Odpowiedzi:
def myfunc(a,b): c = a.intersection(b) return bool(c)
bool()
zrobi coś podobnegonot not
, ale bardziej ideomatycznego i wyraźnego.źródło
bool(...)
kiedy pytasz,is_empty
jest niejasne. Nie wyrażam zamiaru.not not
;). (FTR: już przegłosowałem odpowiedź @gefeis, ale nie mam wpływu na to, co OP zaakceptował…)nie tak pytoniczne jak inne odpowiedzi, ale matematyka:
return len(c) == 0
Jak niektórzy komentatorzy zastanawiali się, jaki wpływ
len(set)
może mieć na złożoność. Jest to O (1), jak pokazano w kodzie źródłowym, ponieważ opiera się na zmiennej, która śledzi użycie zestawu.static Py_ssize_t set_len(PyObject *so) { return ((PySetObject *)so)->used; }
źródło
len(c)
nawet jeślic
jest bardzo duże, co jest niepotrzebne, aby sprawdzić, czy nie ma pustki.set()
(python 3.5.2 w windows)Jeśli chcesz
return True
mieć pusty zestaw, myślę, że byłoby to bardziej przejrzyste:return c == set()
tj. „
c
równa się pustemuset
”.(Lub na odwrót
return c != set()
).Moim zdaniem jest to bardziej wyraźne (choć mniej idiomatyczne) niż poleganie na interpretacji pustego zbioru
False
w Pythonie w kontekście boolowskim.źródło
Jeśli
c
jest zbiorem następnie można sprawdzić, czy jest ona pusta, wykonując:return not c
.Jeśli
c
jest pusty,not c
będzieTrue
.W przeciwnym razie, jeśli
c
zawiera jakieś elementy,not c
będzieFalse
.źródło
Kiedy powiesz:
c is not None
W rzeczywistości sprawdzasz, czy c i None odwołują się do tego samego obiektu. To właśnie robi operator „jest”. W Pythonie None jest specjalną wartością null, co oznacza, że nie masz dostępnej wartości. Sorta jak null w c lub java. Ponieważ Python wewnętrznie przypisuje tylko jedną wartość None, używając operatora „is”, aby sprawdzić, czy coś jest None (myślę, że null) działa, i stał się popularnym stylem. Jednak nie ma to nic wspólnego z wartością prawdziwości zbioru c, chodzi o sprawdzenie, czy c faktycznie jest zbiorem, a nie wartością zerową.
Jeśli chcesz sprawdzić, czy zestaw jest pusty w instrukcji warunkowej, jest rzutowany jako wartość logiczna w kontekście, więc możesz po prostu powiedzieć:
c = set() if c: print "it has stuff in it" else: print "it is empty"
Ale jeśli chcesz, aby został przekonwertowany na wartość logiczną, aby był przechowywany, możesz po prostu powiedzieć:
c = set() c_has_stuff_in_it = bool(c)
źródło
""" 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()
źródło
Nie tak czysty jak bool (c), ale był to pretekst do użycia trójskładnika.
def myfunc(a,b): return True if a.intersection(b) else False
Używając nieco tej samej logiki, nie ma potrzeby przypisywania do c, chyba że używasz go do czegoś innego.
def myfunc(a,b): return bool(a.intersection(b))
Na koniec założyłbym, że chcesz mieć wartość Prawda / Fałsz, ponieważ zamierzasz wykonać z nią jakiś test boolowski. Zalecałbym pominięcie narzutu wywołania funkcji i definicji, po prostu testując tam, gdzie jest to potrzebne.
Zamiast:
if (myfunc(a,b)): # Do something
Może to:
if a.intersection(b): # Do something
źródło