Please take a look at the following codes and explain what’s happening here:

``````a = 256
b = 256
a is b
#True its ok
c = 257
d = 257
c is d
#False why
e = 258; f=258;
e is f
//True
// why?
``````

## All 6 Replies

They are all True on my computer as each pair points to the same address in memory (although I am on a 64 bit computer and it may be different on a 32 bit machine). Python keeps a list of objects for all "small" integers so they don't have several references to the same number in a program. When you create an int in that range you actually just get back a reference to the existing object. So each variable in the pair points to the same existing object. To get a False you would have to point to some calculated number i.e. it is not a reference to an existing object.

``````a = 256  ## lookup in existing list
b = 256
print a is b

c = 257
d = 257
print c is d

e = 258
f=258
print e is f

## create and put in unique memory location
## "256+1" not in list
g = 256+1
print "c is g", c is g, c, g

""" prints
True
True
True
c is g False 257 257
"""
``````

Regarding your 3rd "why", Python performs certain primitive optimizations when it comes to immutable values. For when you write `e=258; f=258` on the same line, Python realizes that it can save some space by making both variables point to the same value. This works not only for numbers but all immutable built-in types.

``````>>> a = 10.1
>>> b = 10.1
>>> a is b
False
>>> a = 10.1; b = 10.1
>>> a is b
True
``````

But realize that this won't happen for mutable types since it results in change of semantics.

``````>>> a = []; b = []
>>> a is b
False
``````

Again, implementation dependent but good to know I guess. :)

commented: Awesome! +14

I didn't know that, this is awesome. I don't think it is an optimisation, for example it does not work in functions

``````>>> def f():
...     a = 10.1
...     b = 10.1
...     print(a is b)
...
>>> def g():
...     a = 10.1; b = 10.1
...     print(a is b)
...
>>> f()
True
>>> g()
True
>>>
``````

I think it has to do with the fact that the interactive interpreter compiles each statement individually into a code object, so that when you write

``````>>> a = 10.1
>>> b = 10.1
``````

two code objects are created and executed one after the other, and when you write

``````>>> a = 10.1; b = 10.1
``````

a single code object is executed. These code objects contain a `LOAD_CONST` (bytecode) statement which loads the constant 10.1 on the stack. This constant is stored in an array aggregated to the code object. When 2 code objects are used, one has two different float objects, but when there is a single code object, the same float object is used.

In the case of functions `f()` and `g()` above, each function is compiled into a single code object, which means that a single float instance is used.

Edit: The following code confirms my theory

``````>>> def f():
...     x = 10.1
...     return x
...
>>> f() is f()
True
>>>
>>> def g():
...     x = 10.1
...     return x
...
>>> f() is g()
False
>>> g() is g()
True
``````

Yup, it's all about the evaluation context/scope. I call this an optimization because it is basically an implementation detail; a naive implementation doesn't have to do it and it will still work fine. I call it basic because it doesn't handle some other basic cases. For e.g. the below snippet

``````def f():
a = (1, 2)
b = (1, 2)
print a is b
``````

printf `False` even though `(1,2)` is a const. The VM could very well have taken care of this when compiling the function object but didn't.

A further look at the memory locations ...

``````>>> a = 10.1
>>> b = 10.1
>>> a is b
False
>>> c = 10.1; d = 10.1
>>> c is d
True
>>> id(a)
4298630584
>>> id(b)
4298631760
>>> id(c)
4298630704
>>> id(d)
4298630704
>>>
``````

`c = 10.1; d = 10.1` behaves more like `c = d = 10.1`

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.