Python - イテラブル・イテレータ
イテレータ(iterator)
イテレータとは
イテレータは次の性質をもつものをいいます。
- 自分自身を戻り値とする
__iter__
メソッドを持つ - 自分が管理している要素列の値を1つずつ返す
__next__
メソッドを持つ __next__
メソッドでは、要素が尽きたらStopIteration例外を発生する
今回は、リストの要素をfor
文を用いて順番に取り出す際の内部処理を見ていくことでイテレータについて解説します。
x = ["a", "b", "c"] # forループを使ってリストの要素を順番に取り出す for element in x: # 取り出した要素を表示 print(element)
上記のコードはリストx
の要素をelement
として順番に取り出しています。
このコードは内部では次のように処理されています。
x = ["a", "b", "c"] # イテレータに変換 itr_obj = iter(x) # 1つめの要素 e1 = next(itr_obj) print(e1) # 2つめの要素 e2 = next(itr_obj) print(e2) # 3つめの要素 e3 = next(itr_obj) print(e3) # 4つめの要素(ない) e4 = next(itr_obj) # error: StopIteration
(内部処理の流れ)
イテラブル(Iterable)
リストや辞書、タプル、集合などは実際には、イテレータではありません。
x = ["a", "b", "c"] print(next(x)) # TypeError: 'list' object is not an iterator
実際、上記のようにnext()
関数で次の要素を取り出すことができません。
__iter__
メソッドを持ち、イテレータに変換できるオブジェクトをイテラブル(Iterable)といいます。イテラブルはfor
文によって繰り返すことができるオブジェクトということもできます。
また、下のように属性の一覧を表示すると、リストや辞書、タプル、集合などはイテラブルではあるが、イテレータではないことが分かります。
x = ["a", "b", "c"] print(dir(x)) # xの属性をリストを表示
(実行結果)
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
__iter__
はあるが、__next__
はないことが確認できます。