0

Whilst reading about Python's infinity, I came accross this :

>>>float('Inf') == float('Inf')
True
>>>float('Inf') is float('Inf')
False
>>>float('Inf') is not float('Inf')
True

I understand that equals works but I am wondering what float('Inf') actually points to that make the is test return False ? Is it different each time you call float('Inf') ?

EDIT: I am not asking about the difference between == and is. I am asking about the implementation details of float('Inf') and the nature of this object.

Jacques Gaudin
  • 15,779
  • 10
  • 54
  • 75
  • 5
    Possible duplicate of [Is there a difference between \`==\` and \`is\` in Python?](http://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python) – GingerPlusPlus May 12 '16 at 15:00
  • That is because `is` compares memory address of two objects, while `==` compares the objects themselves. || As above, while comparing by `is`, you actually create two different objects with same structure in memory. Two objects hold the same structure, but they are not the same, since addresses are different. Think it like universe. – Eray Erdin May 12 '16 at 15:00
  • Yes, I understand that, but what address does it point to ? – Jacques Gaudin May 12 '16 at 15:01
  • 2
    Evidently it makes a new `float` every time you call `float('Inf')` – khelwood May 12 '16 at 15:01
  • 2
    Same reason `float('5.0') is float('5.0')` is false. – user2357112 May 12 '16 at 15:04
  • But `5.0 is 5.0` is `True` – Jacques Gaudin May 12 '16 at 15:06
  • 4
    @JacquesGaudin That's an implementation detail of your interpreter. It's not guaranteed to be true by the language. – chepner May 12 '16 at 15:06
  • @chepner: Interesting. Do you know where I should look in the source to get an idea of how this works ? – Jacques Gaudin May 12 '16 at 15:11
  • I thought it would be as `True` as `int(1.2) is int(1.4)` – Jacques Gaudin May 12 '16 at 15:16
  • 2
    @JacquesGaudin: [Here's the `float` constructor](https://hg.python.org/cpython/file/2.7/Objects/floatobject.c#l1811), which handles `float(thing)`, and [here's the bytecode compiler](https://hg.python.org/cpython/file/2.7/Python/compile.c), where the constant folding that causes `5.0 is 5.0` to be true happens. Remember that anything you read in these files is an implementation detail. – user2357112 May 12 '16 at 15:16
  • You can look in https://github.com/python/cpython/blob/master/Objects/longobject.c (code using `NSMALLPOSINTS` and `NSMALLNEGINTS`) to see how CPython preallocates integers between -5 and 257 and reuses them where possible. I don't think any such preallocation for floats exists, but it *could*. – chepner May 12 '16 at 15:16
  • @user2357112 and chepner: Thanks for understanding the bottom line of the question. – Jacques Gaudin May 12 '16 at 15:19

4 Answers4

2

is and == in python are quite different. is checks for identity while == checks for equality as some other users have already stated here:Is there a difference between == and is in Python?

float() creates (or might create, depending on your interpreter) a new object which is not identical (but is equal) to another object created by float() having the same argument.

Cpython may return a True for your check, but other VMs or interpreters may not as described by Microsoft

So:

 >>> float(2) is float(2)
 >>> False
 >>> float(2) == float(2)
 >>> True

In fact their identities can be seen as completely different using id()

 >>> id(float(2))
 >>> 251452
 >>> id(float(2)) # same call
 >>> 251934       # different result

So you should only use is if you really, really want to test for identity and not value.

Community
  • 1
  • 1
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • 1
    `float()` *might* create a new object; an enterprising interpreter might memorize or preallocate certain values expected to be used commonly. – chepner May 12 '16 at 15:11
  • @chepner Which can readily be seen in python by doing something like `1000 is 1000` and seeing that it is true. However saying `x = 1000` and doing `x is 1000` is not true, for the very reason you just indicated. – zephyr May 12 '16 at 15:17
  • @chepner I just indicated that in an edit. Thank you – Moses Koledoye May 12 '16 at 15:23
0

Simply put, is works on objects and will only return TRUE if and if the 2 variables are pointing to same object , while == works on value so,, the reason it says False is because a new float is called up

Nishant Singh
  • 3,055
  • 11
  • 36
  • 74
0

When you say float('Inf'), you're creating a new object on the fly that gets stored in memory somewhere and has a reference to that memory location. When you do

>>>float('Inf') == float('Inf')

You're creating two such objects, each with the same value, but in two different memory locations. The comparison here will compare the two values in these two memory locations and of course it will come out true.

When you do

>>>float('Inf') is float('Inf')

again you're creating two new objects each of the same value, but in different locations. But now you're trying to compare the references to the memory locations and of course those are not going to be the same.

This may be more clear if you consider the concept of

>>>a = float('Inf')
>>>b = float('Inf')
>>>a == b
True
>>>a is b
False

Hopefully, once you consider that a and b are the actual objects you're creating (rather than creating them with no name as in your examples) it is more clear what is happening.

zephyr
  • 2,182
  • 3
  • 29
  • 51
  • Say "object" rather than "variable". There is some truth to the statement "Python doesn't have variables"; it has names that refer to objects. – chepner May 12 '16 at 15:08
  • That sounds like semantics to me. If you mean variable to be a primitive data type, then yes, python doesn't have variables. But I use variable in a general sense to mean a name that refers to something. In python that something is always an object, but the name is still a variable. – zephyr May 12 '16 at 15:10
  • 1
    'variable' suggests mutability though, in Python you can change what object a name refers to and you can mutate some objects, avoiding the word variable sometimes avoids confusion. – RemcoGerlich May 12 '16 at 15:15
  • @zephyr Which is precisely why `float('Inf') == float('Inf')` does not create any variables; there are no names attached to the objects being created. – chepner May 12 '16 at 15:19
0

And you don't need to invoke float() or 'Inf' to see this:

a = 1. 
b = 1. 
a == b 
True 
a is b 
False

Adding as answer only because I can't get formatting to work properly as a comment to @Nishant response.

ViennaMike
  • 2,207
  • 1
  • 24
  • 38