为什么列表有 __reverse__() 特殊方法而元组没有 Python?
Why do lists have a __reverse__() special method but tuples don't in Python?
Python内置的reversed(seq)
表示seq
必须有__reversed__()
方法或支持序列协议。列表和元组显然都支持序列协议,但列表有自己的 __reversed__()
方法来代替。
>>> hasattr(list, '__reversed__')
True
>>> hasattr(tuple, '__reversed__')
False
那么在 __reverse__()
中必须有一些比顺序协议提供的逆序更快的列表优化。所以我看了一下 source code where __reversed__()
is implemented for listobject.c, and with my pitifully limited C knowledge I cannot understand why a tuple (tupleobject.c) 不会有类似的内部反转方法,因为在我看来元组是 bean 数组,对分配和内存进行了一些优化 (PyTuple_MAXSAVESIZE
),以及一个列表是一个比较熟悉的数组。
我缺少的 C 魔法是什么使得实现 __reversed__()
方法成为列表类型的优化,但标准迭代器协议更适合元组?
元组很少以相反的顺序迭代。
那是因为元组是异构的,列表是同质的;虽然列表有顺序,但元组应该具有 结构 。因此,元组应该相对 小 ,而列表可以(非常)大。参见 What's the difference between lists and tuples?
因此,根本不需要为元组创建反向迭代器;这将是过早的优化,会产生维护成本而收益很小。
Python内置的reversed(seq)
表示seq
必须有__reversed__()
方法或支持序列协议。列表和元组显然都支持序列协议,但列表有自己的 __reversed__()
方法来代替。
>>> hasattr(list, '__reversed__')
True
>>> hasattr(tuple, '__reversed__')
False
那么在 __reverse__()
中必须有一些比顺序协议提供的逆序更快的列表优化。所以我看了一下 source code where __reversed__()
is implemented for listobject.c, and with my pitifully limited C knowledge I cannot understand why a tuple (tupleobject.c) 不会有类似的内部反转方法,因为在我看来元组是 bean 数组,对分配和内存进行了一些优化 (PyTuple_MAXSAVESIZE
),以及一个列表是一个比较熟悉的数组。
我缺少的 C 魔法是什么使得实现 __reversed__()
方法成为列表类型的优化,但标准迭代器协议更适合元组?
元组很少以相反的顺序迭代。
那是因为元组是异构的,列表是同质的;虽然列表有顺序,但元组应该具有 结构 。因此,元组应该相对 小 ,而列表可以(非常)大。参见 What's the difference between lists and tuples?
因此,根本不需要为元组创建反向迭代器;这将是过早的优化,会产生维护成本而收益很小。