Reputation: 37
Can someone explain to me why:
print(my_list[-1])
Is the same as:
print (my_list[len(my_list) - 1])
And how is this a shortcut to avoid writing
len(my_list)
Thanks
Upvotes: 1
Views: 243
Reputation:
Supporting negative indexes is an object specific implementation, who design the list object support it. Not all objects have to support it.
You can find where this is implemented in the listobject.c
:
static PyObject *
list_subscript(PyListObject* self, PyObject* item)
{
if (PyIndex_Check(item)) {
Py_ssize_t i;
i = PyNumber_AsSsize_t(item, PyExc_IndexError);
...
if (i < 0) // 1
i += PyList_GET_SIZE(self); // 2
return list_item(self, i); // 3
...
if the index is negative, it will add the list size to it:
if i < 0:
i += len(lst)
Upvotes: 1
Reputation: 1416
lvc's answer is great, but I would like to add that this is a shortcut because
print (my_list[-1])
is indded shorter than print (my_list[len(my_list) - 1])
, the correct way of doing that.
Upvotes: 0
Reputation: 3397
When doing print(my_list[-1])
you are printing the last value of my_list
. See slicing of python.
When doing print (my_list[len(my_list) - 1])
you are printing the last value of my_list
.
In this way you are getting a positive integer from len(my_list) - 1
.
While len(my_list)
returns the number of elements in my_list
. Note that the slicing notation in python starts with 0 and len
counts elements starting with 1.
Upvotes: 0
Reputation: 35089
This is the case purely because Python defines it to be the case. A negative index is treated as counting from the end of the list (or string, or tuple) instead of the start. To quote the docs, referring to my_list[i]
, and extended forms my_list[i:j]
and my_list[i:j:k]
:
If
i
orj
is negative, the index is relative to the end of the string:len(s) + i
orlen(s) + j
is substituted. But note that -0 is still 0.
Most third-party types implementing the sequence protocol behave the same way, but note that they are not obliged to - it is only guaranteed behavior for the built-in sequences.
Upvotes: 4