2016-10-20 64 views
17

倒車元組和倒車返回列表中不同類型的對象:反轉元組和反轉列表有什麼區別?

>>> reversed((1,2)) 
<reversed at 0x7fffe802f748> 
>>> reversed([1,2]) 
<list_reverseiterator at 0x7fffebdd4400> 

它們具有相同的dir。這兩種類型都不是另一種的子類。

這是爲什麼?其他人不能做什麼?

+0

似乎是沒有什麼區別的酒吧表演,除非你使用python的是舊版本,你可以調用len上listreverseiterator。 http://bugs.python.org/issue3689。 –

回答

12

基本上,列表實現__reversed__方法,並返回一個專門的對象,而tuple回落至reversed任何序列的默認實現:

>>> list.__reversed__ 
<method '__reversed__' of 'list' objects> 
>>> tuple.__reversed__ 
AttributeError: type object 'tuple' has no attribute '__reversed__' 

現在,爲什麼列表不默認爲序列reversed對象必須在列表對象本身的源代碼中找到 - 可能通過直接訪問某些內部list屬性來啓用某些優化。

其實看C代碼,有差別不大,肯定沒有醒目 -

我敢說特別名單__reversed__實現是Python2天剩下的時間,其中reversed實際上將任何其他Python序列複製到list--所以對於其他的sequ因爲它有特殊的情況(當他們確實執行了一般的enumreverse這對元組來說已經足夠了)。

我敢肯定,如果一個人只會註釋掉__reversed__插槽listobject.c,Python和其名單將工作,就像什麼都沒發生過,默認爲一般情況下reversed

+3

默認顛倒過來:https://github.com/python/cpython/blob/master/Objects/enumobject。c#L230列表顛倒:https://github.com/python/cpython/blob/master/Objects/listobject.c#L2823 – BlackBear

+3

其他人不能做什麼? – wim

+5

** Github pro-tip **:如果您像鏈接到blob/master中的行號,則修改文件後鏈接將立即失效。相反,選擇你想要的行,然後按'y'鍵,將鏈接固定到特定的提交。那麼行號永遠不會偏離相關的代碼。我更新了答案中的鏈接。 – wim

4

根據Python的documentation

object.__reversed__(self)

調用(如果存在)由reversed()內置實現逆轉 迭代。它應該返回一個新的迭代器對象,該對象以相反順序遍歷容器中的所有對象。

如果不設置__reversed__()方法,所述reversed() 內置將回退到使用該序列協議(__len__()__getitem__())。支持序列協議 的對象應該只提供__reversed__(),前提是它們可以提供比 reversed()提供的更高效的 實施。

+3

看起來很奇怪,列表會有更有效的實現可用,但是元組沒有。 – wim

+0

是的:D @wim –