2016-05-21 30 views
3

我正在寫一個數獨求解器,並遇到了這個奇怪的行爲。如果我做到以下幾點:爲什麼這些看起來相同的代碼片段的行爲有所不同? (Python 3)

r = range(1,len(board)+1) 
b = block(board,x,y) 
nums = [x for x in r if x not in b] 

nums將是這樣計算它的不同:

nums = [x for x in range(1,len(board)+1) if x not in block(board,x,y)] 

block很簡單如下:

return sum([col[y*N(board):(y+1)*N(board)] 
      for col in board[x*N(board):(x+1)*N(board)]], 
      []) 

哪裏N只是董事會規模的平方根,董事會只是一個數字清單的列表。 (之所以像Nlen到處都是它應該適用於不是9x9的板子)

我的問題很簡單:爲什麼這些東西會不一樣?它只是讀取值並將它們存儲在變量中,而不是將任何東西分配給板本身,所以如果我做b = a然後使用a或僅使用b開始時爲什麼會這樣?

+2

在第一種情況下'x'是什麼?在第二種情況下,你至少要重寫列表理解變量'x'。 – miradulo

+1

我假設你的'block'函數返回某物。第二個版本的每次調用都不同,基於'x'的變化,其中'b'在第一個中始終保持相同。 – schwobaseggl

+0

他們說什麼。請注意,第二個版本不必要地重新計算'block(board,x,y)'len(board)'次。 –

回答

3

在第一個示例中,b計算爲block(board,x,y),使用任何值x在此刻具有。這個值然後被重複用於以下列表理解的所有迭代。

在第二個示例中,x在整個列表理解中發生變化,因此每次迭代時,block(board,x,y)將返回不同的結果。

+0

我在問自己,我是如何忽略這一點的,這很明顯。謝謝! – Wysaard

3

當您使用

r = range(1,len(board)+1) 
b = block(board,x,y) 
nums = [x for x in r if x not in b] 

x是最有可能已經被設置爲某個常數,因此b成爲您的列表理解不變。當你使用第二個列表理解時,x在整個理解中具有不同的值(遍歷r),並且覆蓋功能或模塊級別的任何x - 因此每次檢查x是否在block(board,x,y)中變得依賴於理解迭代。

給你的列表理解變量使用與x不同的名稱,並且注意覆蓋變量名稱。


這裏有一個小例子,在這裏你可以看到變量名x被覆蓋,以及它如何影響每個調用你的函數。

>>> r = range(5) 
>>> x = 1 
>>> b = range(x+1) 
>>> [x for x in r if x not in b] 
[2, 3, 4] 
>>> [x for x in range(5) if x not in range(x+1)] 
[] 
相關問題