2016-10-20 5 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 - так что не было бы смысла для других секторов чтобы иметь для него особые случаи (и когда они реализовали общий enumreverse, это было просто достаточно для кортежей).

Я уверен, что если один просто закомментируйте слот __reversed__ на listobject.c, Python и его списки будут работать так, как будто ничего не произошло, по умолчанию в общем случае reversed.

+3

По умолчанию отменено: https://github.com/python/cpython/blob/master/Objects/enumobject.C# L230 list reverseed: https://github.com/python/cpython/blob/master/Objects/listobject.c#L2823 – BlackBear

+3

Что можно сделать, чтобы другой не мог? – wim

+5

** Github pro-tip **: Если вы ссылаетесь на номер строки в blob/master, то эти ссылки будут сминаться, как только файл будет изменен. Вместо этого выберите нужную строку (линии), а затем нажмите клавишу 'y', чтобы привязать ссылку к определенной фиксации. Тогда номер строки никогда не будет отклоняться от соответствующего кода. Я обновил ссылки в вашем ответе. – wim

4

Согласно documentation Пайтона:

object.__reversed__(self)

Вызывается (если таковой имеется) по reversed() встроенной для реализации обратного итерации. Он должен возвращать новый объект итератора, который выполняет итерацию по всем объектам в контейнере в обратном порядке.

Если метод __reversed__() не предусмотрено, то reversed() встроенный будет падать обратно с использованием протокола последовательности (__len__() и __getitem__()). Объекты, поддерживающие протокол последовательности , должны предоставлять только __reversed__(), если они могут обеспечить реализацию , которая более эффективна, чем та, которая предоставляется reversed().

+3

Кажется странным, что в списке будет более эффективная реализация, но кортеж не работает. – wim

+0

Да точно: D @wim –

 Смежные вопросы

  • Нет связанных вопросов^_^