2

Can someone help me understand the concept of memory spaces linked with the value in python via id command: And Clarify my doubts regarding below code snippet: CASE 1:

>>> a=10
>>> b=10
>>> id(a)
140732845308032
>>> id(b)
140732845308032

CASE 2: But at the same time see below lines and their output from python interpreter:

>>> c=257
>>> d=257
>>> id(c)
140732848419768
>>> id(d)
140732848419840

I have also noticed id of variables containing values of 0-256 has same id value, but beyond that is starts varying.

And another question is can we modify this id value of a variable by any chance. suggest me.

Thanks in Advance.

Anand.G.T
  • 61
  • 6

2 Answers2

1

You can't modify id. The id of an object is assigned at instantiation and cannot be changed during the object's lifetime. In CPython (the standard interpreter) it is actually the memory address of the object, so it is obvious why it can't change; in some other Python implementations, it is simply an auto-incrementing integer, but you still can't change it.

Python does reuse immutable objects sometimes, although this is an implementation detail unique to CPython and other Pythons (or even different versions of CPython) may behave differently. Since the integer object 2 can't be changed, it doesn't matter which instance you use in any given circumstance; for efficiency, Python therefore keeps a pool of "smallish" integers rather than always creating new ones. (Currently these are -5 to 256 inclusive.)

Strings are another type of object that can be reused. String literals are always reused, and you can force other strings to be reused with the intern() function.

The empty tuple is another immutable object that is reused and always has the same id.

What do you do if you need to change the id of an object, and it's not one of those objects that Python always treats as singletons? Copy it. For some types this is easily done using the type itself; e.g. list(my_list) creates a copy of my_list that has a different ID. This is a shallow copy: if the list contained sublists, those aren't copied, but rather a reference to the same sublists appear in both the original list and the copy.

A list object can also be shallowly copied using slice notation, a la my_list[:] (as can tuples and some other sequences).

When you need a full copy, or when you want to copy an object that doesn't have a built-in way to make a copy, the copy module has you covered.

kindall
  • 178,883
  • 35
  • 278
  • 309
1

The id() function gives the memory address of the object in CPython.

However, if we look at the implementation, we can see how integers in the range -5 <= x < 257 all reference the same address in memory.

This is done through initiating a static array of them:

static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS];

which is called after the limits are defined:

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif

Now, when a new integer is created, the PyLong_FromLong function is called and within this CHECK_SMALL_INT is called.

This function then checks the condition:

-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS

before calling get_small_int which finally will lookup are value in the array:

v = (PyObject *)&small_ints[ival + NSMALLNEGINTS]

And that's it, so integers in the range -5 <= x < 257 all reference the same locations in memory, but the other larger ones have their own separate instances; thus causing changes in the result of the id() function.

Joe Iddon
  • 20,101
  • 7
  • 33
  • 54