9

According to the Documentation:

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)

So the following behaviors are normal.

>>> a = 256
>>> b = 256
>>> a is b
True
>>> c = 257
>>> d = 257
>>> c is d
False

But when i declare two variables like these, i am getting True-

>>> e = 258; f=258;
>>> e is f
True

I have checked the identity of the objects referenced by e and f-

>>> id(e)
43054020
>>> id(f)
43054020

They are same.

My question is what is happening when we are declaring e and f by separating with semicolons? Why are they referencing to the same object (though the values are out of the range of Python's array of integer objects) ?

It would be better, if you please explain it like you are explaining it to a beginner.

Community
  • 1
  • 1
ni8mr
  • 1,725
  • 3
  • 31
  • 58
  • 1
    Python caches small integer objects, which is an implementation detail.There's an optimization that allows small integers to be compared with is, but don't rely on it.[relate1](http://stackoverflow.com/questions/2988017/string-comparison-in-python-is-vs),[related2](http://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python) – luoluo Aug 28 '15 at 04:06
  • 4
    To stem the tide of comments about this being a known duplicate, please read the question carefully. This is not the usual small-integer-caching question. I am able to reproduce it, too. `e = 258; f = 258` on the same line, same objects. `e = 258` and `f = 258` on different lines, different objects. Color me surprised. – John Kugelman Aug 28 '15 at 04:08
  • @Cyphase no, i don't think my question is duplicate of that question. I have studied that question and relevant answers earlier. :) – ni8mr Aug 28 '15 at 04:09
  • Is it a speed thing? If I make a script with `e = 258` and `f = 258` as separate statements, they end up the same object. – John Kugelman Aug 28 '15 at 04:10
  • How would speed affect the outcome in any way? – spectras Aug 28 '15 at 04:32
  • Well, if I knew how I'd post an answer instead of a question. – John Kugelman Aug 28 '15 at 04:35
  • 5
    Someday someone will explain to me why people find the implementation details about when immutable objects are reused so fascinating. (And many people seem to.) Anyway, [this answer](http://stackoverflow.com/a/15172182/487339) seems to get into some of the CPython guts, although I'm far too lazy to verify the details myself. – DSM Aug 28 '15 at 04:37
  • John Kugelman raised some cogent points about my suite of statements theory, so I am being a little more cautious now -- but I think that what happens is that caching doesn't work across different iterations of the interpreter REPL loop. The following also leads to `e is f` being true: exec("e = 258 \nf = 258") – John Coleman Aug 28 '15 at 04:40
  • 1
    @JohnKugelman> what I meant is the nature of an interpreter makes it very unlikely that the outcome be affected by speed (barring bugs). That's definitely not where I would start looking. The fact that the first option runs two separate compilations while the second option runs only one would have been my first lead, not the actual time it takes to run them. – spectras Aug 28 '15 at 04:55
  • @DSM, thanks for the link. It answers my query. Though, the answer is very detailed and i have got lost at the end. My question was raised in my mind while doing some calculation. I was not interested in implementation details. :) – ni8mr Aug 28 '15 at 05:30

1 Answers1

5

This is not an unexpected behavior, according to Python Data model it's an implementation detail:

Types affect almost all aspects of object behavior. Even the importance of object identity is affected in some sense: for immutable types, operations that compute new values may actually return a reference to any existing object with the same type and value, while for mutable objects this is not allowed. E.g., after a = 1; b = 1, a and b may or may not refer to the same object with the value one, depending on the implementation, but after c = []; d = [], c and d are guaranteed to refer to two different, unique, newly created empty lists. (Note that c = d = [] assigns the same object to both c and d.)

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • Thanks for the explanation. "for immutable types, operations that compute new values may actually return a reference to any existing object with the same type and value"- so e and f may or may not reference to the same object. So sometimes 'e is f' may return 'False' ? Another question remains regarding e and f are having values out of the range of Python's array of integer objects. – ni8mr Aug 28 '15 at 05:10
  • 1
    @ni8mr depends on the implementation... :) In [CPython](https://en.wikipedia.org/wiki/CPython) this case will *always* return `True`, but other implementations of python might choose a different behavior. – Nir Alfasi Aug 28 '15 at 05:14
  • Should i accept your answer ( as my question seemed duplicate) ? – ni8mr Aug 28 '15 at 05:31
  • @ni8mr only if it satisfied your question :) – Nir Alfasi Aug 28 '15 at 05:32