2011-10-20 10 views
0

在下面的代碼中,當我使用它進行一堆操作後,在第一個循環中打印行時,我看到了我想要的結果。但是,在退出第一個循環後,我發現變量Dataset中的結果不同。我知道這是一個範圍界定問題,但我無法弄清楚問題所在,以及如何獲得我在第一個「打印」聲明中顯示的所需結果。感謝您的幫助python中for循環的作用域問題

import random 
random.seed(1234567) 
Key=[[.5,.5]] 
Dataset=[[0]+[0]*1]*int(10/2) +[[1]+[0]*1]*int(10/2) 

print "results I need" 
for row in Dataset: 
    response=row[0] 
    for i in xrange(len(Key)): 
     if random.random() < Key[i][response]: 
      row[i+1]=response 
     else: 
      row[i+1]=1-response 
    print row 

print "Results I get" 
for row in Dataset: 
    print row 
+0

修改後的腳本請包括實際和預期產出的例子。 –

+2

請注意'[[0]] * 10'實際上並不創建內部列表的拷貝('[0]')。這意味着該列表的所有十個項目將引用相同的列表實例。其中一項改變將反映在其他項目中。 –

+0

非常感謝,這很有意義。 –

回答

3
  • Python有引用語義。您的原始Dataset包含對共同[0, 0][1, 0]子列表的多個引用。 (我也無法理解你爲什麼要使初始化如此複雜。)

你可以通過使用[[0, 0] for i in xrange(5)] + [[1, 0] for i in xrange(5)]來解決這個問題。

  • 其餘的邏輯也是不必要的複雜。我們可以使用條件表達式將兩個分配合並在一起,我們應該使用直接迭代而不是迭代人工索引列表(xrange)。

這看起來像:

for row in Dataset: 
    response = row[0] 
    for k in Key: 
     row[i + 1] = response if random.random() < k[response] else 1 - response 
  • 然而,這仍然不是我們正在尋找的解決方案。實際上沒有理由將所有這些零放在初始化數據中,這些數據將被覆蓋並且從不在循環中讀取。 [i + 1]索引也很笨拙。一個更簡單的解決方案:首先列出子列表的第一個值,然後在循環中構建每個子列表的剩餘部分(我們可以使用列表理解)並在第一個元素前加上。我們可以使用另一個列表理解來將它們綁定在一起,而不是替換Dataset中的元素。

這給了我們:

import random 
random.seed(1234567) 
Key=[[.5,.5]] 
Initial_Conditions=[0]*int(10/2) +[1]*int(10/2) 

Dataset = [ 
    [i] + [ 
     i if random.random() < k[i] else 1 - i 
     for k in Key 
    ] 
    for i in Initial_Conditions 
] 
2

這根本不是一個範圍問題。您錯誤地構建了Dataset,導致它由對同一列表的兩組5個引用組成。

Dataset = [[0]+[0]*1 for x in range(10//2)] + [[1]+[0]*1 for x in range(10//2)] 
0

問題在於如何構建數據集。它的內容並不全是唯一的列表 - 它們中的幾個是完全相同的對象(不僅僅是相同的內容)。這是很容易解決:

Dataset=[[0,1] for i in range(10//2)] + [[1,0] for i in range(10//2)] 
0

它不是劃定範圍的問題,我認爲他想更新數據集,

見下文

import random 
random.seed(1234567) 
Key=[[.5,.5]] 
Dataset=[[0]+[0]*1]*int(10/2) +[[1]+[0]*1]*int(10/2) 

print "results I need" 
for row in range(len(Dataset)): # Changes 
    response=Dataset[row][0] 
    for i in xrange(len(Key)): 
     if random.random() < Key[i][response]: 
      Dataset[row][i+1]=response # Important 
     else: 
      Dataset[row][i+1]=1-response # Important 
    print Dataset[row] 

print "Results I get" 
for row in Dataset: 
    print row