85

私はAlexMarteliのPythonを一言で調べnext()ていますが、この本は、メソッドを持つオブジェクトはすべてイテレーターである(または少なくともイテレーターとして使用できる)ことを示唆しています。また、ほとんどのイテレータは、と呼ばれるメソッドへの暗黙的または明示的な呼び出しによって構築されることも示唆していますiter

本でこれを読んだ後、私はそれを試してみたいという衝動を感じました。私はpython2.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'

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

したがって、もう一度試してみると、今回は少し違った方法で、これを実行しようとしました。

>>> _temp_iter = next(x)

このエラーが発生しました:

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

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

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

誰かが私の心の中でこれを明確にするのを手伝ってもらえますか?

4

5 に答える 5

112

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

于 2012-10-24T17:03:44.183 に答える
27

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
于 2012-10-24T17:03:23.513 に答える
26

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

  • __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,
>>> 
于 2012-10-24T17:44:34.953 に答える
8

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

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

StopIteration例外がスローされるまで使用できるitイテレータオブジェクトが含まれるようになりましたxit.next()

于 2014-07-23T12:47:00.210 に答える
0

リストがイテレータであるがイテレータではないことについては、すでに良い答えがあります。Pythonバージョン>3.0では、以下を使用します

a = [1, 2, 3]
b = iter(a)
b.__next__()
于 2021-05-26T08:23:11.610 に答える