反转元组和反向列表之间的区别是什么?

时间:2016-10-20 22:55:50

标签: python python-internals reverse-iterator

反转元组并反转列表会返回不同类型的对象:

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

他们有相同的dir。这两种类型都不是另一种类型的子类。

为什么?另一个人可以做什么呢?

2 个答案:

答案 0 :(得分: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 - 所以没有任何意义其他序列有特殊情况(当它们实现了通用enumreverse时,它对元组来说已经足够了。)

我很确定如果只是简单地注释掉__reversed__上的listobject.c广告位,那么Python及其列表就会好像什么都没发生一样,默认为一般情况reversed

答案 1 :(得分:4)

根据Python的documentation

  

object.__reversed__(self)

     

reversed()内置调用(如果存在)以实现反向   迭代。它应该返回一个迭代的新迭代器对象   容器中的所有对象的顺序相反。

     

如果未提供__reversed__()方法,reversed()   内置将回退到使用序列协议(__len__()   和__getitem__())。支持序列协议的对象   应该只提供__reversed__(),如果他们可以提供   实现比提供的更有效   reversed()