Was ist die pythonischste Methode, um zu überprüfen, ob mehrere Variablen nicht None sind?

76

Wenn ich ein Konstrukt wie dieses habe:

def foo():
    a=None
    b=None
    c=None

    #...loop over a config file or command line options...

    if a is not None and b is not None and c is not None:
        doSomething(a,b,c)
    else:
        print "A config parameter is missing..."

Was ist die bevorzugte Syntax in Python, um zu überprüfen, ob alle Variablen auf nützliche Werte eingestellt sind? Ist es wie ich geschrieben habe oder ein anderer besserer Weg?

Dies unterscheidet sich von dieser Frage: nicht Keine Test in Python ... Ich suche nach der bevorzugten Methode, um zu überprüfen, ob viele Bedingungen nicht Keine sind. Die Option, die ich eingegeben habe, scheint sehr lang und nicht pythonisch zu sein.

Wimper
quelle
2
Mögliches Duplikat von nicht keiner Test in Python
schwobaseggl
Ich suche nach vier Variablen und dachte auch, dass die offensichtliche Lösung, die Sie veröffentlicht haben, nicht sehr pythonisch ist. Ich bin traurig, aus dem Mangel an Antworten schließen zu müssen, dass es keinen "schöneren" Weg zu geben scheint.
Mi
3
@schwobaseggl: Nein, dies ist kein Duplikat, da es nicht darum geht, wie man nach None sucht. Es geht darum, wie man es "pythonischer aussehen lässt", wenn mehrere Variablen überprüft werden, aber nicht so viele, um die von Daniel Roseman vorgeschlagene Lösung zu korrigieren.
Mi

Antworten:

79

Es ist nichts falsch daran, wie du es machst.

Wenn Sie viele Variablen haben, können Sie diese in eine Liste aufnehmen und Folgendes verwenden all:

if all(v is not None for v in [A, B, C, D, E]):
Daniel Roseman
quelle
103

Es kann wirklich viel einfacher gemacht werden

if None not in (a, b, c, d):
    pass

AKTUALISIEREN:

Wie slashCoder richtig bemerkt hat, führt der obige Code implizit a == None, b == None usw. aus. Diese Praxis ist verpönt. Der Gleichheitsoperator kann überladen werden und nicht None kann gleich None werden. Sie können sagen, dass es nie passiert. Nun, das tut es nicht, bis es es tut. Um auf der sicheren Seite zu sein, können Sie diesen Ansatz verwenden, wenn Sie überprüfen möchten, ob keines der Objekte None ist

if not [x for x in (a, b, c, d) if x is None]:
    pass

Es ist etwas langsamer und weniger ausdrucksstark, aber es ist immer noch ziemlich schnell und kurz.

serge.v
quelle
4
Ja! Und es ist auch 10 mal schneller! (Laut timeit)
Praind
3
Das Problem dabei ist, dass die Operatoren inund not inGleichheitsprüfungen für jedes Element der Sammlung durchführen, von denen in PEP8 abgeraten wird.
SlashCoder
2
Bitte beachten Sie, dass dies eine Yoda-Bedingung ist ( en.wikipedia.org/wiki/Yoda_conditions ) und mit Vorsicht verwendet werden muss.
Chandrahas Aroori
1
@Chandrahas Aroori: Hrrmmm. Seien Sie vorsichtig!
serge.v
6

Ich weiß, dass dies eine alte Frage ist, aber ich wollte eine Antwort hinzufügen, die ich für besser halte.

Wenn alle Elemente, die überprüft werden müssen, hashbar sind, können Sie eine Menge anstelle einer Liste oder eines Tupels verwenden.

>>> None not in {1, 84, 'String', (6, 'Tuple'), 3}

Dies ist viel schneller als die Methoden in den anderen Antworten.

>>> import timeit
>>> timeit.timeit("all(v is not None for v in [1, 84, 'String', (6, 'Tuple'), 3])")
1.7880705000000034
>>> timeit.timeit("None not in [1, 84, 'String', (6, 'Tuple'), 3]")
0.35424169999998867
>>> timeit.timeit("None not in (1, 84, 'String', (6, 'Tuple'), 3)")
0.3454340999999772
>>> timeit.timeit("None not in {1, 84, 'String', (6, 'Tuple'), 3}")
0.09577370000002361
tfpf
quelle
Warum ist Diktat schneller als Liste und Tupel?
zheyuanWang
1
@zheyuanWang Um zu überprüfen, ob ein Element in einer Liste vorhanden ist, wird das Element mit jedem Element der Liste verglichen. Das ist O(n). Im Falle eines Satzes berechnet Python jedoch einfach den Hash des Elements und prüft, ob der Satz einen gültigen Eintrag für diesen Hash hat. Das ist O(1).
25.
4

Schreiben einer separaten Antwort, da ich nicht weiß, wie Code formatiert wird, wenn er als Kommentar hinzugefügt wird.

Die Lösung von Eternal_N00B ist nicht die gleiche wie die von Daniel Roseman. Betrachten Sie zum Beispiel:

>>> all (v ist nicht None für v in [False])
Wahr
>>> alle ([Falsch])
Falsch
Kamaraju Kusumanchi
quelle
2

Für den vom OP vorgelegten konkreten Fall

if not all([a, b, c])

wird genug sein.

all([a, b, c])

wird mit False ausgewertet, wenn ein Parameter fehlt.

Papok
quelle