4

I'm in Python 3.6.5 and I ran across a strange phenomenon: float('50.0') is not the same as float(50.0), though they are equal to each other.

I ran some code to find the difference. Other than python saying that they aren't the same, I can't find a difference. I'm baffled. I'd love it if someone could explain what is happening here.

Here are my tests:

if float('50.0') is float(50.0):
    print("float('50.0') is float(50.0)")
else:
    print("float('50.0') is not float(50.0)")

if float('50.0') == float(50.0):
    print("float('50.0') == float(50.0)")
else:
    print("float('50.0') != float(50.0)")

if float('50.0') is 50.0:
    print("float('50.0') is 50.0")
else:
    print("float('50.0') is not 50.0")

if float(50.0) is 50.0:
    print('float(50.0) is 50.0')
else:
    print('float(50.0) is not 50.0')

if float(50.0) is float(50.0):
    print('float(50.0) is float(50.0)')
else:
    print('float(50.0) is not float(50.0)')

xstr_float = float('50.0')
norm_float = float(50.0)
print ('xstr_float: {0:.100f}'.format(xstr_float))
print ('xstr_float is of type:{}'.format(type(xstr_float)))
print ('norm_float: {0:.100f}'.format(norm_float))
print ('norm_float is of type:{}'.format(type(norm_float)))

and my results:

float('50.0') is not float(50.0)
float('50.0') == float(50.0)
float('50.0') is not 50.0
float(50.0) is 50.0
float(50.0) is float(50.0)
xstr_float: 50.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
xstr_float is of type:<class 'float'>
norm_float: 50.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
norm_float is of type:<class 'float'>

Based on some discussion in the comments I've tried the following, getting results that don't answer the question:

x = float(50.0)
y = float(50.0)
if x is y:
    print('x is y')
else:
    print('x is not y')

x=12345
y=12345
if x is y:
    print('x is y')
else:
    print('x is not y')

results in:

x is y
x is y

UPDATE: I've marked an answer that is correct, and based on a comment on that answer I want to show other people who might be confused what I was missing:

When python creates an object it is assigned an ID. is returns true when comparing two objects returns the same ID. Sometimes python will cache and reuse an object. So in the case of x is y we can see that an object is given and reused because the ID is the same. We also see that the ID changes between python sessions:

x=12345
y=12345
if x is y:
    print('x is y')
else:
    print('x is not y')
print('x_id: {}'.format(id(x)))
print('y_id: {}'.format(id(y)))

results in

x is y
x_id: 2476500365040
y_id: 2476500365040

and on the next run it results in

x is y
x_id: 2234418638576
y_id: 2234418638576

If for any reason the same object couldn't be reused to represent x and y then x is y would return false.

9
  • 3
    Don't compare values with is, use ==. Commented Jun 21, 2018 at 8:55
  • @DanielRoseman it's obvious he is comparing value vs identity which is why both is and == are used Commented Jun 21, 2018 at 8:56
  • 1
    But why would he expect different objects to have the same identity? Commented Jun 21, 2018 at 8:56
  • Observe: x=12345; y=12345; (x is y) == False This has nothing to do with how the float is made. Commented Jun 21, 2018 at 8:59
  • 1
    So to make this perfectly clear, you understand the difference between == and is and you're asking why CPython sometimes re-uses the same float instance and sometimes not? Commented Jun 21, 2018 at 9:13

1 Answer 1

6

I think you might be confused with something that confused me as well in the beginning. is is different than ==.

is will return True if two variables point to the same object.

== will return True if the variables point to objects that are equal.

The answer that helped me understand this is under this question: Is there a difference between == and is in Python?

Sign up to request clarification or add additional context in comments.

3 Comments

Ah. The question that you linked to does a great job of helping me understand. Thanks! So in these cases, it must be that python is "cach[ing] small integer objects, which is an implementation detail. For larger integers, this does not work:"
To add a bit to the understanding. x is y has the same meaning as id(x) == id(y).
@user2653663 your comment was really helpful for rounding out the idea. I updated my question to show what you're getting at for those who have the same question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.