Python Language
イテレータとイテレータ
サーチ…
イテレータとイテレータ対ジェネレータ
iterableは、 イテレータを返すことができるオブジェクトです。 __iter__
メソッドを持ち、イテレータを返す状態のオブジェクトはすべて反復可能です。これは__getitem__
メソッドを実装する状態のないオブジェクトでもあります。 - このメソッドはインデックスがゼロから始まり、インデックスがもはや有効でないときにIndexError
発生させることができます。
Pythonのstr
クラスは、 __getitem__
iterableの例です。
反復子は、あるオブジェクトでnext(*object*)
を呼び出すと、シーケンス内の次の値を生成するオブジェクトです。さらに、 __next__
メソッドを持つオブジェクトはすべてイテレータです。イテレータはイテレータをStopIteration
後にStopIteration
をStopIteration
ため、この時点では再利用できません 。
反復可能なクラス:
反復可能なクラスは__iter__
と__next__
メソッドを定義します。反復可能なクラスの例:
class MyIterable:
def __iter__(self):
return self
def __next__(self):
#code
#Classic iterable object in older versions of python, __getitem__ is still supported...
class MySequence:
def __getitem__(self, index):
if (condition):
raise IndexError
return (item)
#Can produce a plain `iterator` instance by using iter(MySequence())
collections
モジュールから抽象クラスをインスタンス化して、これをよりよく理解しようとしています。
例:
import collections
>>> collections.Iterator()
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods __next__
次のようにして、Python 2の反復可能なクラスに対するPython 3の互換性を処理します。
class MyIterable(object): #or collections.Iterator, which I'd recommend....
....
def __iter__(self):
return self
def next(self): #code
__next__ = next
これらは両方ともイテレータであり、ループすることができます:
ex1 = MyIterableClass()
ex2 = MySequence()
for (item) in (ex1): #code
for (item) in (ex2): #code
ジェネレータはイテレータを作成する簡単な方法です。ジェネレータはイテレータであり、イテレータは反復可能です。
繰り返し可能なもの
Iterableは、アイテムが1つずつ 順番に受信されるものであればどれでもかまい ません 。組み込みのPythonコレクションは繰り返し可能です:
[1, 2, 3] # list, iterate over items
(1, 2, 3) # tuple
{1, 2, 3} # set
{1: 2, 3: 4} # dict, iterate over keys
ジェネレータはiterablesを返します:
def foo(): # foo isn't iterable yet...
yield 1
res = foo() # ...but res already is
iterable全体を反復する
s = {1, 2, 3}
# get every element in s
for a in s:
print a # prints 1, then 2, then 3
# copy into list
l1 = list(s) # l1 = [1, 2, 3]
# use list comprehension
l2 = [a * 2 for a in s if a > 2] # l2 = [6]
iterable内の1つの要素のみを検証する
開梱して最初の要素を抽出し、それが唯一のものであることを確認してください:
a, = iterable
def foo():
yield 1
a, = foo() # a = 1
nums = [1, 2, 3]
a, = nums # ValueError: too many values to unpack
値を1つずつ抽出する
イテレータをiterableで取得するためにiter()
ビルトインから開始し、 next()
を使用して、 StopIteration
が終了を示すまで要素を1つずつ取得します。
s = {1, 2} # or list or generator or even iterator
i = iter(s) # get iterator
a = next(i) # a = 1
b = next(i) # b = 2
c = next(i) # raises StopIteration
イテレータはリエントラントではありません!
def gen():
yield 1
iterable = gen()
for a in iterable:
print a
# What was the first item of iterable? No way to get it now.
# Only to get a new iterator
gen()