2012-08-06 57 views
3

我需要在兩個列表迭代以下列方式:迭代兩個列表,並同步他們

僞代碼:

j=1 
for i=1 to n: 
    print a[i], b[j] 
    while b[j+1] <= a[i]: 
     j++ 
     print a[i], b[j] 

例如:

a = [1 3 5 7] 
b = [2 4 9] 

所需的輸出:

1 2 
3 2 
5 2 
5 4 
7 4 

你是怎麼做的呢cl在python中是否可以使用?

+3

這個問題似乎不完全對我來說,可以根據你解釋你的輸出兩個輸入列表? '9'發生了什麼? – Levon 2012-08-06 17:13:31

+0

@Levon'9'不會顯示在僞代碼的輸出中,就像我翻譯的Python所顯示的那樣。 – murgatroid99 2012-08-06 17:25:12

回答

7

你的僞代碼幾乎可以在Python中工作。那你想要做什麼工作的一些代碼:

a = [1, 3, 5, 7] 
b = [2, 4, 9] 
j = 0 
for i in range(len(a)): 
    print a[i], b[j] 
    while j<len(b)-1 and b[j+1] <= a[i]: 
     j += 1 
     print a[i], b[j] 

注意一些改變,使其在Python工作:

  1. 當聲明列表,是項目之間需要的逗號。
  2. 列表索引從0開始,所以ij都應該從那裏開始。
  3. len(a)返回a長度(4在這種情況下),並通過迭代range(len(a))i執行用於每個整數從0len(a)-1,這是所有索引的在a循環。
  4. Python中不支持++操作,因此我們使用j +=1代替。
  5. 我們必須避免使用b的出界指數,所以我們測試以確保j在遞增之前處於界限內。

該代碼可以通過列表迭代進行更Python如下:

a = [1, 3, 5, 7] 
b = [2, 4, 9] 
j = 0 
for element in a: 
    print element, b[j] 
    while j<len(b)-1 and b[j+1] <= element: 
     j += 1 
     print element, b[j] 

一般情況下,你可能不希望只是打印列表元素,所以對於一個更一般的使用案例你可以創建一個generator,如:

def sync_lists(a, b) 
    if b: 
     j = 0 
     for element in a: 
      yield (element, b[j]) 
      while j<len(b)-1 and b[j+1] <= element: 
       j += 1 
       yield (element, b[j]) 

然後你就可以用

a = [1, 3, 5, 7] 
b = [2, 4, 9] 
for (e1, e2) in sync_lists(a, b): 
    print e1, e2 
如之前打印出來
+0

是的,這看起來很不尋常,以至於僞代碼的直接翻譯可能比一些使用'next'和'itertools'的遊戲更簡單。不過,我可能會將這種迭代邏輯封裝在一個生成器中,這在我看來是最古怪的迭代邏輯的Pythonic「家」。 – DSM 2012-08-06 17:25:00

+0

@DSM這是一個很好的觀點,我將添加一個迭代器版本。 – murgatroid99 2012-08-06 17:26:17

+0

我很好奇 - 你推薦使用'enumerate',但它看起來不像你使用'i'。只是遍歷列表不是更容易嗎? – 2012-08-06 17:35:06

2

murgatroid99's answer生成器代碼可以推廣到任何iterables使用next()而不是指數的算術運算(而不是隻序列):

def sync_list(a, b): 
    b = iter(b) 
    y, next_y = next(b), next(b) 
    for x in a: 
     yield x, y 
     while next_y <= x: 
      y, next_y = next_y, next(b) 
      yield x, y 
+0

請注意,對於錯誤的數組,您可能會開始出現StopIteration異常。我修改了我的代碼以避免相應的IndexError。 – murgatroid99 2012-08-07 13:09:16

+1

@ murgatroid99:'StopIteration'由調用者處理,例如for循環。發生器中「錯誤」陣列不需要特殊處理。 – jfs 2012-08-07 13:24:08

+0

@ J.F.Sebastian,但'b'沒有在for循環中迭代,所以調用者*是*'sync_list'。調用['next'](http://docs.python.org/library/functions.html#next)可以引發該異常,並且在循環中使用它不會神奇地處理它。 – murgatroid99 2012-08-07 13:26:19