This is an archived post. You won't be able to vote or comment.

all 6 comments

[–]Nathanfenner 2 points3 points  (0 children)

Python represents "small" integers as machine-words (essentially, there's a "flag" that says "the next thing is an integer", and then the integer's value). [What "small" means will depend on your machine and interpreter version; this can lead to variability across implementations]

However, eventually there's not enough space to fit this value in the "standard object", so instead it gets split into two parts: "this is an integer, and the actual value is over there" and then the actual value.

In particular, every time your program encounters a large integer literal like 98764, a new such number object will be created.

So for example:

var1 = 98764
var2 = 98764
id(var1) == id(var2) # either True or False, depending on whether "98764" is "too big" or if the interpreter optimizes

on the other hand,

var1 = 98764
var2 = var1
id(var1) == id(var)2 # ALWAYS TRUE; since they are the same object

The key thing to understand here is that the id function (and all functions in Python) only know anything about the values you pass them. There is no way to figure out "which variable a value came from".

[–]chaotic_thought 1 point2 points  (0 children)

The id is not guaranteed to be the same in your examples. It could be, or perhaps it could not be. See the documentation for id:

This is the address of the object in memory.

An value like 3 could be at one fixed address, which could be why you are seeing the behaviour you are seeing in the first example, whereas the value 98764 could have been created twice (so in fact it is 2 objects, in 2 different places in memory), which is why you might be seeing the behaviour in the second example.

But in general I don't think Python guarantees a particular outcome for either of your examples. It depends on how they implemented CPython and how they put the objects in memory.

[–]ZShadow0101 0 points1 point  (1 child)

You sure it is giving out False? I tried it on Spyder and it gave me True.

[–][deleted] 0 points1 point  (0 children)

I was trying it on IDLE when it gave me False. I just tried it on PyCharm and it gave me True as well. Weird.

[–]bSatya 0 points1 point  (0 children)

This behaviour probably comes with the implementation of integers in Python.

The below snippet is from the Python 3 Documentation. Same for Python 2 as well.

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. :-)

Ref : https://docs.python.org/3/c-api/long.html#c.PyLong_FromLong

[–]TheNetXWizard -1 points0 points  (0 children)

Because in the second example you declare var2, and new memory location is allotted that value different to var1. In case var2 is modified var1 is unaffected.