2016-07-25 15 views
2

Ich möchte, dass alle mathematischen Operationen, die eine oder mehrere None-Variablen enthalten, keine zurückgeben.Wie konvertiere ich alle Python-Operationen, die None-Werte enthalten?

Beispiel:

a = None 
b = 7 
a*b 

Ich möchte diese letzte Zeile Keine zurückzukehren, aber es gibt mir stattdessen eine Fehlermeldung:

TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'

Ich verstehe, warum dieser Fehler vorhanden ist, und all das, aber es gibt eine Möglichkeit, das Ergebnis zu zwingen, nur ein None zu sein?

Hintergrund: Ich habe ein paar Funktionen, die Daten abbauen und einen Wert, genannt diff. Später multipliziere oder füge ich diff zu einigen Sachen hinzu, um bedeutungsvolle Informationen zu erhalten, aber nicht alle meine ursprünglichen Daten enthalten ein nützliches diff, also habe ich es eingestellt, diff = None in diesen Fällen zurückzugeben. Ich möchte diese Punkte überspringen können, wenn ich Ergebnisse erstelle. Python scheint keine Probleme zu haben, über None Elemente in einem Array zu springen, wenn ich plane, also möchte ich nur die Ergebnisse der Operationen haben None sein.

+3

einen Schwimmer verwenden ("NaN"), anstatt 'None' – donkopotamus

+1

(http [Wie Attribut Lookups Kette, die keine Rückkehr könnte?]: // Stackoverflow.com/q/15280511); [Vielleicht "Art von" Monade in Python] (http://stackoverflow.com/q/8507200), –

+0

Ähnlich wie @donkopotamus können Sie das Dezimal-Modul und 'Dezimal.Decimal ('NaN')' für 'None' verwenden . Dies ist möglicherweise vorzuziehen, wenn Sie eine korrekt gerundete Dezimalarithmetik wünschen. Wenn alle Ihre Operationen Dezimalzahlen verwenden, funktioniert es so, wie Sie es möchten. – tdelaney

Antwort

2

Anstatt zu versuchen, alle mathematischen Operationen zu zwingen, die einig beliebigen anderen Wert enthält, beliebigen anderen Wert zurückgeben, können Sie einfach einverwenden, die für genau diese Art von Zweck ausgelegt ist:

>>> nan = float("NaN") 
>>> 7 * nan 
nan 
>>> 7 + nan 
nan 

A nan wird in Ihrer mathematischen Operation richtig kaskadieren.

Eine gute Plot-Bibliothek wird auch nan verstehen und sie zur Plot-Zeit weglassen. Wenn nicht, machen Sie einfach Ihren Ersatz von NaN zu None unmittelbar vor dem Plotten.

+0

Genau das, was ich wollte. Vielen Dank. – barriboy

0

Sie auf das Vorhandensein von None in Argumente überprüfen und dann wieder früh:

def calc(*args, **kwargs): 
    if None in list(args) + list(kwargs.keys()): 
     return None 
    #rest 

Sie auch einen Dekorateur schreiben können und die bestehenden Funktionen wickeln, dies nützlich wäre, wenn Sie diesen Vorgang anwenden möchten viele bestehenden Funktionen (oder sogar nur ein, für Klarheit):

def return_none_for_none(f): 
    def wrapped(*args, **kwargs): 
     return None if None in list(args) + list(kwargs.keys()) else f(*args, **kwargs) 
    return wrapped 


@return_none_for_none 
def some_math_exp(a, b, c=2): 
    return a + b*c 
+1

Warum nicht einfach zwei Mitgliedsprüfungen mit 'if None in args oder None in kwargs' verwenden, anstatt aus jeder eine Liste zu erstellen und sie dann zu einer dritten zu kombinieren? – TigerhawkT3

+0

Warum sollten Sie prüfen, ob 'None' ein ** Schlüssel ** in' Kwargs' ist? – donkopotamus

0

Ohne viel Kontext zu Ihrer Code-Struktur zu haben; Ich nehme an, Sie möchten nur eine Operation versuchen und keine zurückgeben, wenn es nicht möglich ist.

Vielleicht ein try/except könnte hier arbeiten:

try: 
    # operation here 
except TypeError: 
    return None 

Jedoch habe ich mit @donkopotamus mit einem NaN Gleitkommawert einverstanden erreicht genau das, was Sie suchen. Wenn der Ausdruck, den Sie auswerten möchten, einen NaN enthält, wird der gesamte Ausdruck zu NaN ausgewertet. Sie können None immer zurückgeben, wenn NaN gefunden wird, oder Ihre Daten konvertieren, wenn Sie sie an die Math-Bibliothek übergeben.

>>> nan = float('NaN') 
>>> nan + 15 ** 4 
nan 
>>> 1000 - nan /6%3 
nan 
>>> 
+0

Pedantisch wird ein 'nan' nicht immer bewirken, dass ein Elternausdruck zu' nan' ausgewertet wird. Betrachte '1 ** nan' oder' nan ** 1'. All diese Regeln für Kaskade sind von anderen sorgfältig durchdacht worden, wir brauchen nicht zu raten ;-) – donkopotamus