ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

Python - イテラブル・イテレータ

初めに

 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

(内部処理の流れ)

  1. リストのような反復可能なオブジェクトをiter()イテレータオブジェクトに変換
  2. next()イテレータオブジェクトから要素を順番に取り出す
  3. イテレータオブジェクトの要素が尽きたら、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__はないことが確認できます。

イテラブルとイテレータの関係

 イテレータ__iter__メソッドを必ず含むためイテラブルです。イテラブルは必ずしも__next__メソッドを持つわけではないため、イテラブルでもイテレータでないことがあります。