Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens when I create a list such as c=[1] in python, in terms of name object bindings?

After reading http://www.effbot.org/zone/python-objects.htm I am left with this question:

In python, if a=1 creates an integer-object and binds it to the name a, b=[] creates an empty list-object and binds it to name b, what happens when I call e.g. c=[1]?

I suppose this creates a list-object and binds it to the name c, but how is the 1 handled exactly? What does the actual content of the list-object look like, under the hood? Does it consist of an integer-object or a reference to a "separate" integer-object? Is it okay to think of e.g. c[0] as a name bound to a list item?

And what about the following:

d=1  # creates int(1)-object and binds it to d
e=[d]  # creates list-object and binds it to e, but what happens with d?

Will the content of the list-object (named e) be a reference to the integer-object called d or a new integer-object?

I guess the answer lies in this quote from Mr. Lundh, from the source mentioned above, but I am still a tiny bit confused:

You’re then calling a method on that object, telling it to append an integer object to itself. This modifies the content of the list object, but it doesn’t touch the namespace, and it doesn’t touch the integer object.

Also I believe part of the answer is found here: Python; name bindings are not object references?, but I am still looking for some more insight.

like image 733
djvg Avatar asked May 18 '17 15:05

djvg


1 Answers

In python, if a=1 creates an integer-object and binds it to the name a, b=[] creates an empty list-object and binds it to name b, what happens when I call e.g. c=[1]?

When you assign c to [1] your telling Python to create a list object with a pointer to an integer object which has the value of 1. This can be seen by looking at how list objects are represented in C under the hood:

typedef struct {
    PyObject_VAR_HEAD
    PyObject **ob_item;
    Py_ssize_t allocated;
} PyListObject;

As you can see from the above example, ob_item is a sequence of pointers where each pointer points to a PyObject in memory. In your case, ob_item contains a pointer which points to the integer object 1.

Is it okay to think of e.g. c[0] as a name bound to a list item?

Not really. when you do c[0] your telling Python to return a pointer to the object at index 0. This again can be observed by looking at what happens when we index a list object at the C level:

Py_INCREF(a->ob_item[i]);
return a->ob_item[i];

And what about the following:

d=1  # creates int(1)-object and binds it to d
e=[d]  # creates list-object and binds it to e, but what happens with d?

In the above example, the the variable d is an alias to the object 1, and e contains a pointer to the object 1. Both d and e[0] point to the same object however:

>>> a = 10
>>> b = [a]
>>> id(a) == id(b[0])
True
>>> 

When you did e = [d] your telling Python to construct a list which contains a pointer to the object which d is referencing.

like image 173
Christian Dean Avatar answered Oct 13 '22 01:10

Christian Dean