Rückgabe des Booleschen Werts, wenn set leer ist

90

Ich habe Probleme, einen saubereren Weg zu finden, um einen booleschen Wert zurückzugeben, wenn mein Satz am Ende meiner Funktion leer ist

Ich nehme den Schnittpunkt zweier Mengen und möchte zurückkehren Trueoder darauf Falsebasieren, ob die resultierende Menge leer ist.

def myfunc(a,b):
    c = a.intersection(b)
    #...return boolean here

Mein erster Gedanke war zu tun

return c is not None

In meinem Interpreter kann ich jedoch leicht erkennen, dass diese Aussage true zurückgibt, wenn c = set([])

>>> c = set([])
>>> c is not None
True

Ich habe auch Folgendes versucht:

>>> c == None
False
>>> c == False
False
>>> c is None
False

Jetzt habe ich aus der Dokumentation gelesen, die ich nur verwenden andkann or, und notmit leeren Mengen, um einen booleschen Wert abzuleiten. Bisher kann ich mir nur vorstellen, nicht zurückzukehren, nicht c

>>> not not c
False
>>> not c
True

Ich habe das Gefühl, dass es einen viel pythonischeren Weg gibt, dies zu tun, indem ich mich bemühe, ihn zu finden. Ich möchte die tatsächliche Menge nicht an eine if-Anweisung zurückgeben, da ich die Werte nicht benötige. Ich möchte nur wissen, ob sie sich überschneiden.

CB
quelle
4
leerer Satz wird als boolesches falsches Äquivalent angesehen, wenn Sie ihn so wirken:bool(set([]))
woozyking
3
übrigens ernsthaft gut ausgearbeitete Frage, was bemerkenswert ist.
Jonas Schäfer
@ JonasWielicki Danke! Schätzen Sie die Antwort - wusste, dass es etwas in diese Richtung war.
CB
Diese Frage wird 5 Jahre alt und niemand hat vorgeschlagen, sie zu verwenden isdisjoint. Ich bin völlig geschockt.
Adirio

Antworten:

67
def myfunc(a,b):
    c = a.intersection(b)
    return bool(c)

bool()wird etwas ähnliches tun not not, aber ideomatischer und klarer.

Jonas Schäfer
quelle
4
Ich lehne es ab, zu schreiben, bool(...)wenn Sie fragen, is_emptyist dunkel. Ich drücke die Absicht nicht aus.
Tamas.kenez
1
@ tamas.kenez Du musst allerdings zugeben, dass es klarer ist als not not;). (FTR: Ich hatte bereits @gefeis Antwort positiv bewertet, aber ich habe keinen Einfluss auf die Sache, die OP akzeptiert hat ...)
Jonas Schäfer
101

nicht so pythonisch wie die anderen Antworten, aber Mathematik:

return len(c) == 0

Wie einige Kommentare fragten, len(set)könnte dies Auswirkungen auf die Komplexität haben. Es ist O (1), wie im Quellcode gezeigt, da es auf einer Variablen basiert , die die Verwendung des Satzes verfolgt.

static Py_ssize_t
set_len(PyObject *so)
{
    return ((PySetObject *)so)->used;
}
gefei
quelle
9
Ich denke das ist eigentlich besser. Es macht klarer, was Ihre Absicht ist.
Arshajii
4
Ich fürchte, dies muss berechnet werden, len(c)auch wenn ces sehr groß ist, was nicht erforderlich ist, um die Leere zu überprüfen.
Michele De Pascalis
1
@Glaedr Ich glaube, dass cpython len für häufig verwendete Datenstrukturen (dh Liste, Menge) O (1) ist (dh sie speichern eine Variable in der Datenstruktur, die die Länge darstellt)
CB
2
^ +1 @CB Ich habe einige Tests mit len ​​(c) durchgeführt und es ist definitiv eine Variable, die len darstellt, da es einen vernachlässigbaren Laufzeitunterschied gab, wenn die eingestellte Größe dramatische Größenordnungen änderte.
dster77
1
@ dster77 Ich profilierte meinen Code mit beiden Versionen und es war deutlich schneller im Vergleich zu set()(Python 3.5.2 in Windows)
Mathiasfk
22

Wenn Sie return Truefür ein leeres Set möchten , dann denke ich, wäre es klarer zu tun:

return c == set()

dh " cist gleich einem leeren set".

(Oder umgekehrt return c != set()).

Meiner Meinung nach ist dies expliziter (wenn auch weniger idiomatisch), als sich auf Pythons Interpretation einer leeren Menge wie Falsein einem booleschen Kontext zu verlassen.

Jonrsharpe
quelle
2
Tatsächlich ist es sehr akzeptabel, sich auf Pythons Interpretation zu verlassen. Solange seine Grenzen beachtet werden.
Vulkan
17

Wenn ces sich um einen Satz handelt, können Sie überprüfen, ob er leer ist, indem Sie Folgendes tun : return not c.

Wenn cleer ist, not cwird es sein True.

Andernfalls wird, wenn cElemente enthalten not csein False.

Simeon Visser
quelle
6

Wenn du sagst:

c is not None

Sie prüfen tatsächlich, ob c und None auf dasselbe Objekt verweisen. Das macht der Operator "ist". In Python ist None ein spezieller Nullwert, was herkömmlicherweise bedeutet, dass kein Wert verfügbar ist. Sorta wie null in c oder java. Da Python intern nur einen None-Wert zuweist, wird mit dem Operator "is" überprüft, ob etwas None ist (think null), und es ist zum beliebten Stil geworden. Dies hat jedoch nicht mit dem Wahrheitswert der Menge c zu tun, sondern prüft, ob c tatsächlich eine Menge und kein Nullwert ist.

Wenn Sie überprüfen möchten, ob eine Menge in einer bedingten Anweisung leer ist, wird sie im Kontext als Boolescher Wert umgewandelt, sodass Sie einfach sagen können:

c = set()
if c:
   print "it has stuff in it"
else:
   print "it is empty"

Wenn Sie jedoch möchten, dass es in einen Booleschen Wert konvertiert wird, können Sie einfach sagen:

c = set()
c_has_stuff_in_it = bool(c)
Andrew Allaire
quelle
1
"""
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()
shtut shtuzim
quelle
0

Nicht so sauber wie bool (c), aber es war eine Ausrede, ternär zu verwenden.

def myfunc(a,b):
    return True if a.intersection(b) else False

Wenn Sie ein bisschen der gleichen Logik verwenden, müssen Sie c nicht zuweisen, es sei denn, Sie verwenden es für etwas anderes.

def myfunc(a,b):
    return bool(a.intersection(b))

Schließlich würde ich annehmen, dass Sie einen True / False-Wert möchten, da Sie damit eine Art Booleschen Test durchführen werden. Ich würde empfehlen, den Overhead eines Funktionsaufrufs und einer Definition zu überspringen, indem Sie einfach testen, wo Sie ihn benötigen.

Anstatt:

if (myfunc(a,b)):
    # Do something

Vielleicht das:

if a.intersection(b):
    # Do something
Amos Baker
quelle