Python: Usable Max and Min values
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 None
s and int
s, 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)
).
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.
In cPython, the cmp does not perform a conversion to float implicitly. i.e., this works:
>>> float('inf') > 2**5000
True
While this explicitly performs the dread conversion:
>>> float('inf') > float(2**5000)
Overflow...
The correct answer, IMHO, is not a value per se by a change in logic:
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...
If you want to have a value then float('-inf')
for min and float('inf')
is pretty safe. Be sure to cache that outside of a loop however:
def func():
minval=float('-inf')
for loop in now_you_can_loop:
# otherwise float('-inf') is kinda slow