4-2

イテラブルとイテレータ

イテラブルとイテレータの関係イテラブルlist, str, dict...iter()イテレータ要素を1つずつ返すnext()値を取得1 → 2 → 3 → ...for文はiter()とnext()を自動的に呼び出している

イテラブルとは

イテラブル(iterable)とは、for ループで繰り返し処理できるオブジェクトのことです。リスト、タプル、文字列、辞書、ファイルオブジェクトなどがイテラブルです。

python
# イテラブルの例for x in [1, 2, 3]:      print(x)   # リストfor ch in "Python":      print(ch)  # 文字列for k in {"a": 1}:       print(k)   # 辞書(キー)for i in range(3):       print(i)   # range

イテレータとは

イテレータ(iterator)は、next() を呼び出すたびに次の値を返すオブジェクトです。値が尽きると StopIteration 例外を発生させます。

python
# iter() でイテレータを取得lst = [1, 2, 3]it = iter(lst)next(it)   # 1next(it)   # 2next(it)   # 3next(it)   # StopIteration(値が尽きた)

for ループの仕組み

for x in iterable: は、内部的に以下と同じです。

python
iterable = [1, 2, 3]it = iter(iterable)while True:    try:        x = next(it)        print(x)    except StopIteration:        break

ジェネレータ

ジェネレータは、yield キーワードを使って値を1つずつ生成するイテレータです。全ての値をメモリに保持しないため、大きなデータの処理に効率的です。

python
def count_up(start, stop):    """start から stop まで1ずつ数える"""    n = start    while n < stop:        yield n   # 値を返してここで一時停止        n += 1gen = count_up(1, 4)next(gen)   # 1next(gen)   # 2next(gen)   # 3next(gen)   # StopIteration
python
# for ループでも使えるfor x in count_up(1, 6):    print(x)   # 1, 2, 3, 4, 5

無限シーケンス

ジェネレータで無限シーケンスを作ることができます。

python
def natural_numbers():    """自然数を無限に生成"""    n = 1    while True:        yield n        n += 1gen = natural_numbers()next(gen)   # 1next(gen)   # 2next(gen)   # 3  ... 永遠に続く

よく使うイテレータ関連の関数

zip, enumerate(再掲)

python
# zip: 複数のイテラブルをまとめるlist(zip([1, 2, 3], ["a", "b", "c"]))   # [(1, "a"), (2, "b"), (3, "c")]# 長さが異なる場合は短い方に合わせるlist(zip([1, 2, 3], ["a", "b"]))   # [(1, "a"), (2, "b")]

map, filter

python
# map: 各要素に関数を適用nums = [1, 2, 3, 4, 5]list(map(lambda x: x ** 2, nums))   # [1, 4, 9, 16, 25]# filter: 条件を満たす要素を抽出list(filter(lambda x: x % 2 == 0, nums))   # [2, 4]

itertools モジュール

python
import itertools# chain: 複数のイテラブルを連結list(itertools.chain([1, 2], [3, 4], [5]))   # [1, 2, 3, 4, 5]# combinations: 組み合わせlist(itertools.combinations("ABC", 2))   # [("A","B"), ("A","C"), ("B","C")]# permutations: 順列list(itertools.permutations("AB", 2))    # [("A","B"), ("B","A")]# product: デカルト積list(itertools.product([1, 2], ["a", "b"]))   # [(1,"a"), (1,"b"), (2,"a"), (2,"b")]

練習: ジェネレータ関数

標準

n 以下の全ての素数を生成するジェネレータ関数 primes_up_to(n) を定義してください。