1

I'm looking for a Python object which is guaranteed to compare greater than any given int. It should be portable, platform-independent and work on both Python 2.7+ and 3.x.

For example:

x = float('inf')
while True:
    n = next(my_gen)
    if my_calc(n):
        x = min(n, x)
        if my_cond(x):
            break

Here I've used float('inf') for this purpose because it seems to behave correctly. But this feels dirty, because I think it relies on some underlying float specification and I don't know whether that's going to be platform dependent or break in unexpected ways.

I'm aware that I could create my own class and define the comparison operators, but I thought there might be an existing built-in way.

Is it safe to use float('inf') like this? Is there a less ugly way of creating this "biggest integer"?

wim
  • 266,989
  • 79
  • 484
  • 630

3 Answers3

9

float('inf') is guaranteed to test as larger than any number, including integers. This is not platform specific.

From the floatobject.c source code:

else if (!Py_IS_FINITE(i)) {
    if (PyInt_Check(w) || PyLong_Check(w))
        /* If i is an infinity, its magnitude exceeds any
         * finite integer, so it doesn't matter which int we
         * compare i with.  If i is a NaN, similarly.
         */
        j = 0.0;

Python integers themselves are only bounded by memory, so using 10 ** 3000 is not going to be big enough, probably.

float('inf') is always available; Python will handle underlying platform specifics for you to make this so.

Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997
1

Why don't just use:

x = float('inf')

instead of:

x = 1e3000

Read this post for more information.

Community
  • 1
  • 1
Christian
  • 31,246
  • 6
  • 45
  • 67
0

In the following I remove the need for that first sentinel x value by using an outer while loop to capture the first valid x then using it on the preserved inner while loop:

while True:
    n = next(my_gen)
    if my_calc(n):
        x = n
        if my_cond(x):
            break
        else:
            while True:
                n = next(my_gen)
                if my_calc(n):
                    x = min(n, x)
                    if my_cond(x):
                        break  
            break

It is more code. Usually the removal of sentinel values is good but the above would have to be assessed for maintainability.

Further factoring of the code gives the following, but the code above preserves more of the original conditionals.

while True:
    n = next(my_gen)
    if my_calc(n):
        x = n
        if not my_cond(x):
            while True:
                n = next(my_gen)
                if my_calc(n):
                    x = min(n, x)
                    if my_cond(x):
                        break  
        break
Paddy3118
  • 4,262
  • 23
  • 33
  • Could be @wim, but sentinels values have their own detractors too. Think of how unsure you were, leading to you having to ask this question, and people having to check the Python source to ensure that a comparison between any int and float('inf') will work the way you want it to. I guess you could use either method and comment with a link to this SO question :-) – Paddy3118 Dec 29 '13 at 11:29
  • p.s. Not needing a sentinel makes the code Duck-typing friendly. If you defined your own type that was not comparable to floats but was returned by my_cond and my_calc then all would remain OK. – Paddy3118 Dec 29 '13 at 11:34