2010-12-21 71 views
1

基本上它應該採用一組座標並返回其鄰居的座標列表。然而,當它擊中的位置:爲什麼這段代碼返回一個列表索引錯誤?

if result[i][0] < 0 or result[i][0] >= board.dimensions: 
    result.pop(i) 

i爲2,它給了我一個了指數的錯誤。我可以設法讓它打印結果[2] [0],但是在if語句中拋出錯誤。這是爲什麼發生?

def neighborGen(row,col,board): 
    """ 
    returns lists of coords of neighbors, in order of up, down, left, right 
    """ 

    result = [] 
    result.append([row-1 , col]) 
    result.append([row+1 , col]) 
    result.append([row , col-1]) 
    result.append([row , col+1]) 

    #prune off invalid neighbors (such as (0,-1), etc etc) 
    for i in range(len(result)): 
     if result[i][0] < 0 or result[i][0] >= board.dimensions: 
      result.pop(i) 
     if result[i][1] < 0 or result[i][1] >= board.dimensions: 
      result.pop(i) 

    return result 

回答

4

您可以從列表中迭代索引,然後繼續從列表中刪除元素。最終你會遇到一個不再存在的索引。改用列表理解來過濾。

result = [entry for entry in result if entry[0] >= 0 and 
    entry[0] < board.dimensions and entry[1] >= 0 and 
    entry[1] < board.dimensions] 
+0

我應該用這段代碼替換整個for循環嗎?我在理解語法方面有點麻煩。 – mmmeff 2010-12-21 05:18:49

+0

是的,它取代了整個for循環。 http://docs.python.org/tutorial/datastructures.html#list-comprehensions – 2010-12-21 05:19:40

+0

非常感謝您的救命!此外,鏈接到pydocs頁面是一個真棒觸摸。祝你有愉快的一天。 – mmmeff 2010-12-21 05:20:17

2

在其降低result大小for循環,你如雨後春筍般冒出的元素。然而,i仍然會從0到4.

2

如果彈出一個元素,它不再在列表中 - 但是您的索引不會移動,所以它現在指向下一個元素。假設你彈出兩個元素...你的列表大小之後將是2,但for循環仍將嘗試去4.

+0

我不能相信我錯過了。非常感謝你。任何想法如何解決它? – mmmeff 2010-12-21 05:14:32

0

正如其他人所說,其餘元素的索引在您刪除來自列表中間的元素。爲了避免出現問題,你可以處理來自最後一個索引的元素先:

for i in range(len(result)-1, -1, -1): 
    ... 

現在,在當前元素被刪除,只對已經處理的元素指標變化。由於這些元素已經被處理並且不需要再次被訪問,因此它們的索引是否不再有效並不重要。

1
def neighborGen(row,col,board): 
    """ 
    returns lists of coords of neighbors, in order of up, down, left, right 
    """ 

    return [ 
     x for x in (
      [row-1 , col], [row+1 , col], [row , col-1], [row , col+1] 
     ) 
     if x[0] >= 0 and x[0] < board.dimensions and 
     x[1] >= 0 and x[1] < board.dimensions 
    ] 
0

避免這種板外測試的規範方法是在板的邊緣有一個或兩個行/列的緩衝區。除了通常的「空白」或者哪一方擁有廣場上的哪種類型的棋子,特殊的「無效」代碼以外,董事會的職位也會有。這通常會與一個董事會代表一起作爲一維數組。

例如,國際象棋將使用大小爲120的數組(10列×12行)。爲了迎合騎士的需要,你需要2的邊距......每一端有2排,但你只需要一個垂直邊距,因爲它可以共享。

E.g.

KNIGHT_DELTAS = (-21, -19, -12, -8, 8, 12, 19, 21) 
# I have a knight at "currpos"; what are its options? 
for delta in KNIGHT_DELTAS: 
    newpos = currpos + delta 
    target = board[newpos] 
    if target & EMPTY: 
     can_move_to(newpos) 
    elif target & OTHER_TEAM: 
     can_capture(at=newpos, captured_piece=target & PIECE_VALUE) 
    else: 
     # Either off the board or occupied by MY_TEAM. 
     # Notice that we didn't even need to test explicitly for "off the board". 
     pass 
1

使用列表理解刪除無效點。例如:

result = [coords for coords in result 
      if all(0 <= c < board.dimension for c in coords)]