2012-05-14 15 views
21

Python 2.x ermöglicht den Vergleich heterogener Typen.Python: Max- und Min-Werte verwendbar

Eine nützliche Verknüpfung (in Python 2.7) Hier ist, dass None vergleicht die kleiner als eine ganze Zahl oder Gleitkommawert:

>>> None < float('-inf') < -sys.maxint * 2l < -sys.maxint 
True 

Und in Python 2.7 ein leeres Tupel () einen unendlichen Wert ist:

>>>() > float('inf') > sys.maxint 
True 

Diese Verknüpfung ist nützlich, wenn Sie eine gemischte Liste von Ints und Floats sortieren und ein absolutes Minimum und Maximum zum Referenzieren haben möchten.

Diese Verknüpfung in Python 3000 wurde jedoch entfernt (dies ist Python 3.2):

>>> None < 0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: NoneType() < int() 

Außerdem Python3000 has removedsys.maxint auf der Theorie, dass alle ints longs und die Grenze nicht mehr zu fördern gilt.

PEP 326, Ein Fall für obere und untere Werte, erweiterte eine Referenz Min und Max in Python. Das neue Bestellverhalten documented.

Seit PEP 326 abgelehnt wurde, was sind brauchbare, verwendbare Definitionen für einen Min- und Max-Wert, die mit Integers und Floats funktionieren und sich auf Python 2X und Python 3000 sehnen?

bearbeiten

Mehrere Antworten entlang der Linien sind „nur verwenden maxv = Schwimmer (‚inf‘)“ ... Der Grund, ich denke jedoch entfernte die Möglichkeit, ist dies:

>>> float(2**5000) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
OverflowError: long int too large to convert to float 

Und:

>>> cmp(1.0**4999,10.0**5000) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
OverflowError: (34, 'Result too large') 

Doch:

>>>() > 2**5000 
True 

Um einen Float-Wert cmp, float('inf') würde der Long-Wert muss einen Schwimmer umgewandelt werden und die Umwandlung würde verursacht ein OverflowError ...

Fazit

Vielen Dank an all für deine Antworten und Kommentare. Ich TryPyPy den gepflückt answer weil es schien, die meisten Inline mit dem, was ich frage: ein absoluten größten und absoluten kleinsten Wert wie in der Wikipedia beschrieben entry on infinity.

Mit dieser Frage habe ich gelernt, dass ein lange oder int-Wert nicht in einen float umgewandelt um den Vergleich von float('inf') > 2**5000 zu vervollständigen. Das wusste ich nicht.

+2

Was ist falsch mit 'float (" inf ")' oder, wenn Sie eine Nummer benötigen, 'sys.float_info.max'? –

+1

IIRC hetrogenous Werte wurden alphabetisch nach dem Namen ihres Typs sortiert - kaum jemals nützlich –

+3

"Python3000 hat sys.maxint auf die Theorie entfernt, dass alle Eingänge zu Longs fördern und das Limit nicht mehr gilt.", Nein, Python3000 hat 'int '* Zeitraum *. Alle ganzen Zahlen sind jetzt "lang", weshalb sie umbenannt wurde. –

Antwort

10

Für numerische Vergleiche sollte +- float("inf") funktionieren.

EDIT: Es funktioniert nicht immer (aber deckt die realistischen Fälle):

print(list(sorted([float("nan"), float("inf"), float("-inf"), float("nan"), float("nan")]))) 
# NaNs sort above and below +-Inf 
# However, sorting a container with NaNs makes little sense, so not a real issue. 

Objekte haben, die als höher oder niedriger zu anderen beliebigen Objekten vergleichen (einschließlich inf, aber ohne andere Betrüger wie unten), können Sie Klassen erstellen, die für Vergleiche ihre max/min-ness in ihren speziellen Methoden angeben: die ‚oder gleich‘ Varianten abzudecken

class _max: 
    def __lt__(self, other): return False 
    def __gt__(self, other): return True 

class _min: 
    def __lt__(self, other): return True 
    def __gt__(self, other): return False 

MAX, MIN = _max(), _min() 

print(list(sorted([float("nan"), MAX, float('inf'), MIN, float('-inf'), 0,float("nan")]))) 
# [<__main__._min object at 0xb756298c>, nan, -inf, 0, inf, nan, <__main__._max object at 0xb756296c>] 

natürlich dauert es mehr Aufwand. Und es löst nicht das generelle Problem, eine Liste mit None s und int s nicht sortieren zu können, aber das sollte auch mit ein wenig Wrapping und/oder decorate-sort-undecorate magic möglich sein (zB Sortieren einer Tupelliste von (typename, value)).

+1

FWIW, diese Art von Betrug bricht, wenn Sie plötzlich viele MINs (oder gleichwertige Betrüger) in einem Container haben, noch schlimmer, wenn es sich um eine automatische Sortierung handelt. – TryPyPy

9

Sie haben die offensichtlichste Wahl in Ihrer Frage bereits: float('-inf') und float('inf').

Beachten Sie auch, dass None weniger als alles, und das leere Tupel höher als alles, was nicht immer war garantiert in Py2, und zB Jython und PyPy sind durchaus berechtigt, eine andere Anordnung zu verwenden, wenn sie glauben, wie es. Alles, was garantiert wird, ist die Konsistenz innerhalb einer laufenden Kopie des Interpreters - die tatsächliche Reihenfolge ist beliebig.

+0

Sie können sogar die float Formen der Unendlichkeit 'MAX' und' MIN' zuweisen und auf Ihrem Weg sein. – mgold

+4

'3 >> Schwimmer ('- inf') <(3 + 4j)' ' Traceback (jüngste Aufforderung zuletzt):' ' File "" Linie 1 in ' ' Typeerror: unorderable Typen: float()

+1

@ IgnacioVazquez-Abrams: nicht wirklich fair, da jede Liste, die nur komplexe Zahlen enthält, auch unportabel ist (und jedes Paar von Komplexen) :) – TryPyPy

3

In cPython führt die cmp implizit keine Konvertierung durch. dh das funktioniert:

>>> float('inf') > 2**5000 
True 

Während dies ausdrücklich die Umwandlung Angst führt:

>>> float('inf') > float(2**5000) 
Overflow... 

Die richtige Antwort, IMHO, ist kein Wert an sich durch eine Änderung in der Logik:

def func_with_min(): 
    minval=None 
    for loop in list_with_mins: 
     if minval is None or minval<minseen: 
      # do that min thing you wanna do... 

Wenn Sie möchten einen Wert dann float('-inf') für min undhabenist ziemlich sicher. Stellen Sie jedoch sicher, dass Sie das außerhalb einer Schleife zwischenspeichern:

def func(): 
    minval=float('-inf') 
    for loop in now_you_can_loop: 
     # otherwise float('-inf') is kinda slow 
+0

'>>> cmp (1.0 ** 4999.10.0 ** 5000)' –

+3

OK - '>>>()> 10.0 ** 5000' erzeugt auch einen Überlauf ... –

+2

und' cmp() 'ist weg in Py3 auch. –

Verwandte Themen