Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Usable Max and Min values

Python 2.x allows heterogeneous types to be compared.

A useful shortcut (in Python 2.7 here) is that None compares smaller than any integer or float value:

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

And in Python 2.7 an empty tuple () is an infinite value:

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

This shortcut is useful when one might sort a mixed list of ints and floats and want to have an absolute minimum and maximum to reference.

This shortcut has been removed in Python 3000 however (this is Python 3.2):

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

Furthermore, Python3000 has removed sys.maxint on the theory that all ints promote to longs and the limit no longer applies.

PEP 326, A Case for Top and Bottom Values, advanced a reference min and max in Python. The new ordering behavior documented.

Since PEP 326 was rejected, what are useful, useable definitions for a min and max value that work with integers and floats and longs on Python 2X and Python 3000?

Edit

Several answers are along the lines of "just use maxv=float('inf')"... The reason I am thinking, however remote the possibility, is this:

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

And:

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

Yet:

>>> () > 2**5000 True 

In order to cmp to a float value, float('inf'), the long value would need to be converted to a float and the conversion would cause an OverflowError...

Conclusion

Thank you everyone for your answers and comments. I picked TryPyPy's answer because it seemed most inline with what I was asking: an absolute greatest and absolute least value as described in the Wikipedia entry on infinity.

With this question, I learned that a long or int value is not converted to a float in order to complete the comparison of float('inf') > 2**5000. I did not know that.

like image 276
the wolf Avatar asked May 14 '12 01:05

the wolf


People also ask

How do you find the max and min value in Python?

Use Python's min() and max() to find smallest and largest values in your data. Call min() and max() with a single iterable or with any number of regular arguments. Use min() and max() with strings and dictionaries.

Is there a max value in Python?

The max int limit in Python 2 is 9223372036854775807, and anything above this number will be converted automatically into long.

What is the smallest float in Python?

The smallest is sys. float_info. min (2.2250738585072014e-308) and the biggest is sys. float_info.


2 Answers

For numerical comparisons, +- float("inf") should work.

It doesn't always work (but covers the realistic cases):

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. 

To have objects that compare as higher or lower to any other arbitrary objects (including inf, but excluding other cheaters like below), you can create classes that state their max/min-ness in their special methods for comparisons:

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>] 

Of course, it takes more effort to cover the 'or equal' variants. And it will not solve the general problem of being unable to sort a list containing Nones and ints, but that too should be possible with a little wrapping and/or decorate-sort-undecorate magic (e.g. sorting a list of tuples of (typename, value)).

like image 82
TryPyPy Avatar answered Sep 21 '22 16:09

TryPyPy


You have the most obvious choices in your question already: float('-inf') and float('inf').

Also, note that None being less than everything and the empty tuple being higher than everything wasn't ever guaranteed in Py2, and, eg, Jython and PyPy are perfectly entitled to use a different ordering if they feel like it. All that is guaranteed is consistency within one running copy of the interpreter - the actual order is arbitrary.

like image 31
lvc Avatar answered Sep 20 '22 16:09

lvc