20

タプルを反転し、リストを反転すると、異なる型のオブジェクトが返されます。

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

彼らは同じdirです。どちらの型も他方のサブクラスではありません。

何故ですか?一方ができて他方ができないことは何ですか?

4

2 に答える 2

14

基本的に、リストは__reversed__メソッドを実装し、特殊なオブジェクトを返しますが、任意のシーケンスtupleのデフォルトの実装にフォールバックします:reversed

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

さて、リストがデフォルトでシーケンス オブジェクトにならない理由はreversed、リスト オブジェクト自体のソース コードで見つける必要があります。おそらく、いくつかの内部list属性に直接アクセスすることで、いくつかの最適化が可能になります。

実際に C コードを見ると、違いはほとんどなく、特に目立ったものはありません。

特別なリストの実装は、 実際に他の Python シーケンスを a にコピーする__reversed__Python2 の時代の残り物 だと思います。タプルには十分でした)。reversedlistenumreverse

__reversed__のスロットをコメントアウトするだけ でlistobject.c、Python とそのリストが何も起こらなかったかのように機能し、デフォルトで一般的なケースになると確信していますreversed

于 2016-10-20T23:07:37.087 に答える
5

Pythonのドキュメントによると:

object.__reversed__(self)

reversed()逆反復を実装するために組み込みによって呼び出されます (存在する場合) 。コンテナー内のすべてのオブジェクトを逆の順序で繰り返す新しい iterator オブジェクトを返す必要があります。

__reversed__()メソッドが提供されていない場合、reversed() ビルトインはシーケンス プロトコル (__len__() および__getitem__()) を使用するようにフォールバックします。シーケンス プロトコルをサポートするオブジェクトは、__reversed__()によって提供される実装よりも効率的な実装を提供できる場合に のみ提供する必要がありreversed()ます。

于 2016-10-20T23:12:42.480 に答える