2012-04-24 7 views
1

最初のループがイテレータを使用し、2番目がジェネレータを使用する2Dループが必要ですが、この単純な関数がうまく動作しませんでした。ジェネレータとイテレータでPythonマルチループが失敗した

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 

なぜわからないのですか?いずれかが助けることができれば、事前に感謝します。

答えて

1

明確にするように依頼したので、もう少し詳しくお話します。しかし実際にはIgnacioの答えはそれをかなりうまくまとめています。ジェネレータを一度しか反復することはできません。あなたの例のコードは、それを3回反復しようとします。aの各値に対して1回です。この単純な例を考えて、私が何を意味するかを確認するには

mygenが呼び出されると

>>> def mygen(x): 
...  i = 0 
...  while i < x: 
...   yield i 
...   i += 1 
... 
>>> mg = mygen(4) 
>>> list(mg) 
[0, 1, 2, 3] 
>>> list(mg) 
[] 

、それは正確に一度巡回できないオブジェクトを作成します。あなたがもう一度それを繰り返ししようとすると、あなたは空のiterableを取得します。

これは、回繰り返す必要があるため、新たに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]] 
+0

ありがとう、あなたの記事が役に立ちます。 – j5shi

2

bを超える最初の反復は、ジェネレータを消費します。

+0

申し訳ありませんが、もっと具体的なのでしょうか? – j5shi

関連する問題