あなたが説明を求めてきたので、もう少し言います。しかし、実際にはIgnacioの答えは、それをかなりうまくまとめています。ジェネレーターを反復処理できるのは1回だけです。この例のコードは、の値ごとに1回ずつ、3回繰り返しますa
。
私が何を意味するかを理解するために、この単純な例を考えてみましょう。
>>> def mygen(x):
... i = 0
... while i < x:
... yield i
... i += 1
...
>>> mg = mygen(4)
>>> list(mg)
[0, 1, 2, 3]
>>> list(mg)
[]
がmygen
呼び出されると、1回だけ繰り返すことができるオブジェクトが作成されます。もう一度反復しようとすると、空の反復可能オブジェクトが得られます。
これは、繰り返したい場合は毎回mygen
、新たに電話をかける必要があることを意味します。つまり、(かなり冗長なスタイルを使用して)...
>>> def make_n_lists(gen, gen_args, n):
... list_of_lists = []
... for _ in range(n):
... list_of_lists.append(list(gen(*gen_args)))
... return list_of_lists
...
>>> make_n_lists(mygen, (3,), 3)
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
引数をジェネレーターにバインドし、それを引数のない関数として渡したい場合は、これを行うことができます(より簡潔なスタイルを使用して)。
>>> def make_n_lists(gen_func, n):
... return [list(gen_func()) for _ in range(n)]
...
>>> make_n_lists(lambda: mygen(3), 3)
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
はlambda
無名関数を定義するだけです。上記はこれと同じです:
>>> def call_mygen_with_3():
... return mygen(3)
...
>>> make_n_lists(call_mygen_with_3, 3)
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]