1

最初のループがイテレータを使用し、2 番目のループがジェネレータを使用する 2D ループが必要ですが、この単純な関数は機能しませんでした。誰かチェックしてもらえますか?

def alphabet(begin, end):
    for number in xrange(ord(begin), ord(end)+1):
        yield chr(number)

def test(a, b):
    for i in a:
        for j in b:
            print i, j

test(xrange(8, 10), alphabet('A', 'C'))

The result shows:
>>> 8 A
>>> 8 B
>>> 8 c

なぜかわからない?誰かが助けてくれるなら、前もって感謝します。

4

2 に答える 2

2

最初の繰り返しでbジェネレーターが消費されます。

于 2012-04-24T02:22:52.953 に答える
1

あなたが説明を求めてきたので、もう少し言います。しかし、実際には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]]
于 2012-04-24T02:46:44.253 に答える