web-dev-qa-db-ja.com

pythonリストと混同:それらはイテレーターですか?

私は勉強している Alex MarteliのPython簡単に言えば =であり、本はnext()メソッドを持つオブジェクトは(または少なくともとして)iterator。ま​​た、ほとんどのイテレータはiterと呼ばれるメソッドの暗黙的または明示的な呼び出しによって構築されることを示唆しています。

本でこれを読んだ後、私はそれを試してみたい衝動を感じました。 python 2.7.3インタープリターを起動し、これを行いました:

_>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for number in range(0, 10):
...     print x.next()
_

しかし、結果はこれでした:

_Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
AttributeError: 'list' object has no attribute 'next'
_

混乱して、dir(x)を介してxオブジェクトの構造を調べようとしましたが、___iter___関数オブジェクトがあることに気付きました。そのため、そのタイプのインターフェースをサポートしている限り、イテレーターとして使用できることがわかりました。

したがって、私がもう一度試したとき、今回はこれとは少し異なり、これを試みました:

_>>> _temp_iter = next(x)
_

私はこのエラーを受け取りました:

_Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator
_

しかし、リストはこのインターフェイスをサポートしているように見えるので、どのようにイテレータにできません。また、次のコンテキストでリストとして確実に使用できます。

_>>> for number in x:
...     print x
_

誰かがこれを頭の中ではっきりさせるのを手伝ってもらえますか?

66
NlightNFotis

これらは反復可能ですが、反復子ではありません。それらはiter()に渡されて、暗黙的に(たとえばfor経由で)または明示的にイテレータを取得できますが、それ自体はイテレータではありません。

最初にiter()を使用してリストをイテレータに変換する必要があります。

In [7]: x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [8]: it=iter(x)

In [9]: for i in range(10):
    it.next()
   ....:     
   ....:     
Out[10]: 0
Out[10]: 1
Out[10]: 2
Out[10]: 3
Out[10]: 4
Out[10]: 5
Out[10]: 6
Out[10]: 7
Out[10]: 8
Out[10]: 9

In [12]: 'next' in dir(it)
Out[12]: True

In [13]: 'next' in dir(x)
Out[13]: False

オブジェクトがイテレータであるかどうかの確認:

In [17]: isinstance(x,collections.Iterator)
Out[17]: False

In [18]: isinstance(x,collections.Iterable)
Out[18]: True

In [19]: isinstance(it,collections.Iterable) 
Out[19]: True

In [20]: isinstance(it,collections.Iterator)
Out[20]: True
22

イテレータとイテレータの違いについて混乱している場合に備えて。イテレータは、データのストリームを表すオブジェクトです。イテレータプロトコルを実装します。

  • __iter__メソッド
  • nextメソッド

イテレータのnext()メソッドを繰り返し呼び出すと、ストリーム内の連続したアイテムが返されます。使用可能なデータがなくなると、イテレータオブジェクトが使い果たされ、next()メソッドをさらに呼び出すとStopIterationが再度発生します。

一方、反復可能なオブジェクトは__iter__メソッドを実装します。このメソッドは、呼び出されるとイテレータを返します。これにより、データを複数回渡すことができます。反復可能なオブジェクトは再利用可能であり、使い果たされると再び繰り返されます。 iter関数を使用して、イテレータに変換できます。

したがって、リスト(反復可能)がある場合は、次のことができます。

>>> l = [1,2,3,4]
>>> for i in l:
...     print i,
1 2 3 4
>>> for i in l:
...     print i,
 1 2 3 4

リストをイテレーターに変換する場合:

>>> il = l.__iter__()  # equivalent to iter(l)
>>> for i in il:
...     print i,
 1 2 3 4
>>> for i in il:
...     print i,
>>> 
18
Vicent

リストはイテレータではありませんが、リストにはイテレータオブジェクト___iter___が含まれているため、リストでforループを使用しようとすると、forループは___iter___メソッドを呼び出してイテレータオブジェクトを取得し、次にnext()メソッドを使用しますリスト。

_x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
it = x.__iter__()
_

itにはxのイテレータオブジェクトが含まれ、StopIteration例外がスローされるまでit.next()として使用できます

4
Kaushal