Tupel und Ternär- und Positionsparameter

8

Gegeben:

%Vor%

Ich habe eine (wie nicht änderbare) 2-Positionsparameterfunktion, bei der die Positionsparameter immer in aufsteigender Reihenfolge sein sollen; d. h., f(2,3) , egal, welche zwei Argumente ich verwende ( f(a,b) ist dasselbe wie f(c,d) im Beispiel)

Ich weiß, dass ich tun könnte:

%Vor%

Oder ich könnte tun:

%Vor%

( Hinweis die Notwendigkeit für Tupel-Klammern in dieser Form wegen , hat eine niedrigere Priorität als das ternäre ...)

Oder

%Vor%

All diese Dinge erscheinen irgendwie klatschig. Gibt es eine andere Syntax, die ich vermisse?

Bearbeiten

Ich habe eine Python-Zwei-Mitglieder-Tupel-Methode der "alten Schule" verpasst. Indexieren Sie ein Zwei-Mitglieder-Tupel basierend auf der Methode True == 1, False == 0:

%Vor%

Auch:

%Vor%

Bearbeiten Sie 2

Der Grund für diese dumme Übung: numpy.isclose hat Folgendes Verwendungshinweis:

  

Für endliche Werte verwendet isclose die folgende Gleichung, um zu testen, ob   zwei Gleitkommawerte sind äquivalent.

     

absolut (a - b) & lt; = (atol + rtol * absolut (b))

     

Die obige Gleichung ist in a und b nicht symmetrisch, so dass iclose (a, b)   könnte in einigen seltenen Fällen von Isclose (b, a) abweichen.

Ich würde das lieber nicht machen.

Ich suche den schnellsten Weg, um sicherzustellen, dass die Argumente für numpy.isclose in einer konsistenten Reihenfolge sind. Deshalb scheue ich mich vor f(*sorted([c,d]))

    
dawg 19.05.2017, 20:51
quelle

3 Antworten

6

Implementiert meine Lösung für den Fall, dass jemand anderes sucht.

%Vor%

Auch seit @Tadhg McDonald-Jensen erwähnen, dass Sie möglicherweise nicht in der Lage sind, die Funktion selbst zu ändern, dass Sie die Funktion als solche verpacken könnten

%Vor%     
Keifer Sebastian 19.05.2017 21:10
quelle
5

Sie erwähnen, dass Ihr Anwendungsfall np.isclose ist. Ihr Ansatz ist jedoch kein guter Weg, das Problem real zu lösen. Aber es ist verständlich angesichts der schlechten Argumentation, die diese Funktion nennt - es impliziert, dass beide Argumente austauschbar sind. Wenn es wäre: numpy.isclose(measured, expected, ...) (oder so ähnlich) wäre es viel klarer.

Wenn Sie beispielsweise den Wert 10 und den Wert 10.51 erwarten und eine Abweichung von 5% zulassen, müssen Sie np.isclose(10.51, 10, ...) verwenden, um ein nützliches Ergebnis zu erzielen würde falsche Ergebnisse erhalten:

%Vor%

Es ist klar zu sehen, dass die erste das richtige Ergebnis liefert, weil der tatsächlich gemessene Wert nicht innerhalb der Toleranz des erwarteten Wertes ist . Das liegt daran, dass die relative Unsicherheit ein "Attribut" des erwarteten Werts ist, nicht des Werts, mit dem Sie ihn vergleichen!

Die Lösung dieses Problems durch "Sortieren" der Parameter ist einfach falsch. Das ist ein bisschen so, als würde man den Zähler und den Nenner für die Division ändern, weil der Nenner Nullen enthält und die Division durch Null NaN , Inf , eine Warnung oder eine Exception ergeben könnte ... es vermeidet das Problem, aber nur durch ein falsches Ergebnis (Der Vergleich ist nicht perfekt, weil es bei der Division fast immer ein falsches Ergebnis ergibt; bei isclose ist es selten).

Dies war ein etwas künstliches Beispiel, um dieses Verhalten auszulösen, und meistens ist es nicht wichtig, wenn Sie measured, expected oder expected, measured verwenden, aber in den wenigen Fällen, in denen es darauf ankommt, können Sie es nicht durch Austauschen der Argumente (außer wenn Sie kein "erwartetes" Ergebnis haben, aber das passiert selten - zumindest sollte es nicht).

Es gab einige Diskussionen zu diesem Thema, als math.isclose zur Python-Bibliothek hinzugefügt wurde:

  

Symmetrie (PEP 485)

     

[...]

     

Welcher Ansatz am geeignetsten ist, hängt davon ab, welche Frage gestellt wird. Wenn die Frage lautet: "Sind diese beiden Zahlen nahe beieinander?", Gibt es keine offensichtliche Ordnung, und ein symmetrischer Test ist am besten geeignet.

     

Wenn jedoch die Frage lautet: "Liegt der berechnete Wert innerhalb von x% dieses bekannten Werts?", dann ist es angemessen, die Toleranz auf den bekannten Wert zu skalieren, und ein asymmetrischer Test ist am besten geeignet.

     

[...]

     

Dieser Vorschlag [für math.isclose ] verwendet einen symmetrischen Test.

Wenn also Ihr Test in die erste Kategorie fällt und Sie einen symmetrischen Test mögen, dann math.isclose könnte eine praktikable Alternative sein (zumindest wenn Sie mit Skalaren zu tun haben):

  

math.isclose (a, b, *, rel_tol = 1e-09, abs_tol = 0.0)

     

[...]

     

rel_tol ist die relative Toleranz - es ist die maximal erlaubte Differenz zwischen a und b relativ zum größeren absoluten Wert von a oder b . Um beispielsweise eine Toleranz von 5% festzulegen, übergeben Sie rel_tol=0.05 . Die Standardtoleranz ist 1e-09 , wodurch sichergestellt wird, dass die beiden Werte innerhalb von etwa 9 Dezimalziffern gleich sind. rel_tol muss größer als Null sein.

     

[...]

Nur für den Fall, dass diese Antwort Sie nicht überzeugen kann und Sie immer noch einen sorted -Ansatz verwenden möchten - dann sollten Sie nach den Werten abs olute von Ihnen sortieren (d. h. *sorted([a, b], key=abs) ). Andernfalls können Sie überraschende Ergebnisse beim Vergleich negativer Zahlen erhalten:

%Vor%     
MSeifert 19.05.2017 22:19
quelle
2

Für nur zwei Elemente im Tupel ist das zweite - meiner Erfahrung nach - das bevorzugte Idiom. Es ist schnell, lesbar, usw.

Nein, es gibt nicht wirklich eine andere Syntax. Es gibt auch

%Vor%

... aber das ist den anderen Methoden nicht besonders überlegen; nur eine andere Art, es auszudrücken.

Hinweis nach Kommentar von dawg :

Eine Klasse mit benutzerdefinierten Vergleichsoperatoren könnte dasselbe Objekt für min und max zurückgeben.

    
Prune 19.05.2017 20:56
quelle

Tags und Links