What is the id( ) function used for?

Python

Python Problem Overview


I read the Python 2 docs and noticed the id() function:

> Return the “identity” of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

>CPython implementation detail: This is the address of the object in memory.

So, I experimented by using id() with a list:

>>> list = [1,2,3]
>>> id(list[0])
31186196
>>> id(list[1])
31907092 // increased by 896
>>> id(list[2])
31907080 // decreased by 12

What is the integer returned from the function? Is it synonymous to memory addresses in C? If so, why doesn't the integer correspond to the size of the data type?

When is id() used in practice?

Python Solutions


Solution 1 - Python

Your post asks several questions:

> What is the number returned from the function?

It is "an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime." (Python Standard Library - Built-in Functions) A unique number. Nothing more, and nothing less. Think of it as a social-security number or employee id number for Python objects.

> Is it the same with memory addresses in C?

Conceptually, yes, in that they are both guaranteed to be unique in their universe during their lifetime. And in one particular implementation of Python, it actually is the memory address of the corresponding C object.

> If yes, why doesn't the number increase instantly by the size of the data type (I assume that it would be int)?

Because a list is not an array, and a list element is a reference, not an object.

> When do we really use id( ) function?

Hardly ever. You can test if two references are the same by comparing their ids, but the is operator has always been the recommended way of doing that. id( ) is only really useful in debugging situations.

Solution 2 - Python

That's the identity of the location of the object in memory...

This example might help you understand the concept a little more.

foo = 1
bar = foo
baz = bar
fii = 1

print id(foo)
print id(bar)
print id(baz)
print id(fii)

> 1532352
> 1532352
> 1532352
> 1532352

These all point to the same location in memory, which is why their values are the same. In the example, 1 is only stored once, and anything else pointing to 1 will reference that memory location.

Solution 3 - Python

Rob's answer (most voted above) is correct. I would like to add that in some situations using IDs is useful as it allows for comparison of objects and finding which objects refer to your objects.

The later usually helps you for example to debug strange bugs where mutable objects are passed as parameter to say classes and are assigned to local vars in a class. Mutating those objects will mutate vars in a class. This manifests itself in strange behavior where multiple things change at the same time.

Recently I had this problem with a Python/Tkinter app where editing text in one text entry field changed the text in another as I typed :)

Here is an example on how you might use function id() to trace where those references are. By all means this is not a solution covering all possible cases, but you get the idea. Again IDs are used in the background and user does not see them:

class democlass:
    classvar = 24

    def __init__(self, var):
        self.instancevar1 = var
        self.instancevar2 = 42

    def whoreferencesmylocalvars(self, fromwhere):
        return {__l__: {__g__
                    for __g__ in fromwhere
                        if not callable(__g__) and id(eval(__g__)) == id(getattr(self,__l__))
                    }
                for __l__ in dir(self)
                    if not callable(getattr(self, __l__)) and __l__[-1] != '_'
                }

    def whoreferencesthisclassinstance(self, fromwhere):
        return {__g__
                    for __g__ in fromwhere
                        if not callable(__g__) and id(eval(__g__)) == id(self)
                }

a = [1,2,3,4]
b = a
c = b
democlassinstance = democlass(a)
d = democlassinstance
e = d
f = democlassinstance.classvar
g = democlassinstance.instancevar2

print( 'My class instance is of', type(democlassinstance), 'type.')
print( 'My instance vars are referenced by:', democlassinstance.whoreferencesmylocalvars(globals()) )
print( 'My class instance is referenced by:', democlassinstance.whoreferencesthisclassinstance(globals()) )

OUTPUT:

My class instance is of <class '__main__.democlass'> type.
My instance vars are referenced by: {'instancevar2': {'g'}, 'classvar': {'f'}, 'instancevar1': {'a', 'c', 'b'}}
My class instance is referenced by: {'e', 'd', 'democlassinstance'}

Underscores in variable names are used to prevent name colisions. Functions use "fromwhere" argument so that you can let them know where to start searching for references. This argument is filled by a function that lists all names in a given namespace. Globals() is one such function.

Solution 4 - Python

id() does return the address of the object being referenced (in CPython), but your confusion comes from the fact that python lists are very different from C arrays. In a python list, every element is a reference. So what you are doing is much more similar to this C code:

int *arr[3];
arr[0] = malloc(sizeof(int));
*arr[0] = 1;
arr[1] = malloc(sizeof(int));
*arr[1] = 2;
arr[2] = malloc(sizeof(int));
*arr[2] = 3;
printf("%p %p %p", arr[0], arr[1], arr[2]);

In other words, you are printing the address from the reference and not an address relative to where your list is stored.

In my case, I have found the id() function handy for creating opaque handles to return to C code when calling python from C. Doing that, you can easily use a dictionary to look up the object from its handle and it's guaranteed to be unique.

Solution 5 - Python

I am starting out with python and I use id when I use the interactive shell to see whether my variables are assigned to the same thing or if they just look the same.

Every value is an id, which is a unique number related to where it is stored in the memory of the computer.

Solution 6 - Python

If you're using python 3.4.1 then you get a different answer to your question.

list = [1,2,3]
id(list[0])
id(list[1])
id(list[2])

returns:

1705950792   
1705950808  # increased by 16   
1705950824  # increased by 16

The integers -5 to 256 have a constant id, and on finding it multiple times its id does not change, unlike all other numbers before or after it that have different id's every time you find it. The numbers from -5 to 256 have id's in increasing order and differ by 16.

The number returned by id() function is a unique id given to each item stored in memory and it is analogy wise the same as the memory location in C.

Solution 7 - Python

The is operator uses it to check whether two objects are identical (as opposed to equal). The actual value that is returned from id() is pretty much never used for anything because it doesn't really have a meaning, and it's platform-dependent.

Solution 8 - Python

The answer is pretty much never. IDs are mainly used internally to Python.

The average Python programmer will probably never need to use id() in their code.

Solution 9 - Python

It is the address of the object in memory, exactly as the doc says. However, it has metadata attached to it, properties of the object and location in the memory is needed to store the metadata. So, when you create your variable called list, you also create metadata for the list and its elements.

So, unless you an absolute guru in the language you can't determine the id of the next element of your list based on the previous element, because you don't know what the language allocates along with the elements.

Solution 10 - Python

I have an idea to use value of id() in logging.
It's cheap to get and it's quite short.
In my case I use tornado and id() would like to have an anchor to group messages scattered and mixed over file by web socket.

Solution 11 - Python

I'm a little bit late and i will talk about Python3. To understand what id() is and how it (and Python) works, consider next example:

>>> x=1000
>>> y=1000
>>> id(x)==id(y)
False
>>> id(x)
4312240944
>>> id(y)
4312240912
>>> id(1000)
4312241104
>>> x=1000
>>> id(x)
4312241104
>>> y=1000
>>> id(y)
4312241200

You need to think about everything on the right side as objects. Every time you make assignment - you create new object and that means new id. In the middle you can see a "wild" object which is created only for function - id(1000). So, it's lifetime is only for that line of code. If you check the next line - you see that when we create new variable x, it has the same id as that wild object. Pretty much it works like memory address.

Solution 12 - Python

As of in python 3 id is assigned to a value not a variable. This means that if you create two functions as below, all the three id's are the same.

>>> def xyz():
...     q=123
...     print(id(q))
...
>>> def iop():
...     w=123
...     print(id(w))
>>> xyz()
1650376736
>>> iop()
1650376736
>>> id(123)
1650376736

Solution 13 - Python

Be carefull (concerning the answer just below)...That's only true because 123 is between -5 and 256...

In [111]: q = 257                                                         

In [112]: id(q)                                                            
Out[112]: 140020248465168

In [113]: w = 257                                                         

In [114]: id(w)                                                           
Out[114]: 140020274622544

In [115]: id(257)                                                         
Out[115]: 140020274622768

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThanakron TandavasView Question on Stackoverflow
Solution 1 - PythonRobᵩView Answer on Stackoverflow
Solution 2 - PythonbrbcodingView Answer on Stackoverflow
Solution 3 - PythonArijanView Answer on Stackoverflow
Solution 4 - PythonFatalErrorView Answer on Stackoverflow
Solution 5 - PythonLongtomjrView Answer on Stackoverflow
Solution 6 - PythonDhvanan ShahView Answer on Stackoverflow
Solution 7 - PythonomzView Answer on Stackoverflow
Solution 8 - PythonGareth LattyView Answer on Stackoverflow
Solution 9 - PythonLajos ArpadView Answer on Stackoverflow
Solution 10 - PythonDaniil IaitskovView Answer on Stackoverflow
Solution 11 - PythonTomasView Answer on Stackoverflow
Solution 12 - PythonAsish KumarView Answer on Stackoverflow
Solution 13 - PythongeeView Answer on Stackoverflow