2012-04-24 73 views
1

我需要一個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的回答總結得非常好:你只能迭代一次發生器。在你的例子中的代碼試圖迭代它三次,每個值在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被調用時,它創建能夠通過迭代只有一次的對象。當你嘗試迭代它時,你會得到一個空的迭代器。

這意味着你必須重新撥打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]] 

如果你想你的論點綁定到你的發電機和傳遞,作爲一個argumentless功能,你可以這樣做(用更簡潔的風格) :

>>> 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 2012-04-24 03:08:59

2

b的第一次迭代消耗了發生器。

+0

對不起,您能不能更具體些? – j5shi 2012-04-24 02:25:50