2014-04-19 75 views
1

有人能向我解釋爲什麼:索引操作

print(my_list[-1]) 

是一樣的:

print (my_list[len(my_list) - 1]) 

而且這是怎麼一個快捷方式,避免寫

len(my_list) 

感謝

回答

0

在做print(my_list[-1])時,您正在打印最後一個值my_list。參見python的切片。

在做print (my_list[len(my_list) - 1])時,您正在打印最後一個值my_list。 通過這種方式,您可以從len(my_list) - 1獲得正整數。

雖然len(my_list)返回my_list中的元素數。需要注意的是在Python切片符號與0和len計數元素與1

4

這種情況純粹是因爲Pytho n將其定義爲這種情況。負數索引被視爲從列表末尾(或字符串或元組)開始計數,而不是開始計數。引用the docs,參照my_list[i],和擴展形式my_list[i:j]my_list[i:j:k]

i如果或j是否定的,該索引是相對於所述字符串的末尾: len(s) + ilen(s) + j被取代。不過需要注意的是-0仍然是0。

大多數第三方類型實現序列協議的行爲方式相同,但請注意,他們不是義務 - 它只能保證行爲內置序列。

+1

'slice.indices'是得心應手。假定序列長度爲5,並且要求切片'[-1 :: -1]',即'__getitem__'傳遞'slice(-1,None,-1)'。然後'start,stop,step = slice(-1,None,-1).indices(5); (開始,停止,步驟)==(4,-1,-1)'。 – eryksun

0

LVC的答案是偉大的開始啓動,但是我想補充一點,這是一條捷徑,因爲 print (my_list[-1])是indded短於print (my_list[len(my_list) - 1]),正確的方法這樣做。

1

支持負向索引是一個對象特定的實現,設計列表對象的人支持它。並非所有對象都必須支持它。

你可以找到這個地方在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 i < 0: 
    i += len(lst) 
+1

那麼,如果一個類型只支持序列方法,那麼['PySequence_Getitem'](http://hg.python.org/cpython/file/04f714765c13/Objects/abstract.c#l1498)會對負索引進行翻譯。大多數支持'tp_as_mapping-> mp_subscript',因爲它是'PyObject_Getitem'的首選,並支持擴展切片。但不是,例如['_collections.deque'](http://hg.python。組織/ CPython的/文件/ 04f714765c13 /模塊/ _collectionsmodule.c#l1150)。負索引通過'PySequence_Getitem'支持,但不能切片,因爲'tp_as_sequence-> sq_item'帶有'ssize_t'索引。 – eryksun