2012-08-15 79 views
2

以下是我編寫的計算第n個素數的代碼片段。 我初始化arr = [2,3,5]; prime(arr,n)應該修改arr以包含前n個素數。但是,在執行prime(arr,n)之後,arr不會反映更改。 我讀過列表是作爲參考類型傳遞的,所以在下面的代碼中有什麼問題。 t表示驗證必須完成的測試用例的數量。Python中的引用類型列表

該程序導致錯誤,指出數組索引超出了arr的限制。

import sys; 
def prime (arr,n): 
    while(len(arr)< n): 
     num=arr[len(arr)-1]+1;prime=0; 
     while(prime==0): 
      prime = 1 
      for val in arr: 
       if(num%val==0): 
        prime=0; 
        break; 
      if(prime == 1): 
       print "hello"; 
       arr = arr + [num];print arr; print "--"; 
      else: 
       num = num+1; 


t=raw_input(); 
t=int(t); 
arr=[2,3,5]; 
ans =[]; 
for v in range (0,t): 
    n = raw_input(); 
    n = int(n); 
    if(n<=len(arr)): 
     ans = ans + [arr[n-1]]; 
    else: 
     prime(arr,n);print arr;print"arr was printed" 
     ans= ans + [arr[n-1]]; 
print ans;print 'ans '; 
下面

是上述代碼的樣品運行

>>> 
1 
4 
hello 
[2, 3, 5, 7] 
-- 
[2, 3, 5] 
arr was printed 

Traceback (most recent call last): 
    File "C:\Users\Pulkit\Desktop\Random\nth_prime.py", line 30, in <module> 
    ans= ans + [arr[n-1]]; 
IndexError: list index out of range 

感謝提前:)

+1

我覺得你的縮進是關閉的。提示SO上的正確縮進:每個縮進級別使用4個空格,不要使用TAB('\ t')。 – 2012-08-15 20:51:45

+1

其實我從Python腳本複製代碼,所以\ t也被複制。下次會照顧。 – Dynamite 2012-08-15 20:53:57

+1

在Python中,這個arr [len(arr)-1]應該寫成像這樣arr [-1] – stonemetal 2012-08-15 20:58:18

回答

7

更改的行:

arr = arr + [num]; 

arr.append(num) 

新行實際上更改了arr陣列。原來的行並沒有改變它;它創造了一個變量稱爲arr(這是一個rebinding operation instead of a mutating one)本次變動後

採樣運行:

1 
4 
hello 
[2, 3, 5, 7] 
-- 
[2, 3, 5, 7] 
arr was printed 
[7] 
ans 
+2

說明:'arr.append'實際上改變了arr'指向的對象,而'arr = arr + [num ]'創建一個新列表並重新分配名稱'arr'來指向那個新列表,保留傳入的舊列表不變。 – Dougal 2012-08-15 20:56:29

+0

感謝您的解釋:) – Dynamite 2012-08-15 20:59:18

1

list是引用類型(是否作爲參數傳遞與否)這是真的。但是,這具有明確定義的含義,與通過引用不同。作爲引用類型的東西僅僅意味着它總是通過抽象句柄引用,而不是被複制(例如,在變量賦值上)。因此,可變引用類型可以從多個位置進行變異 - 例如從另一個函數中進行變異。

在您的具體情況下,使用arr.append(...)而不是arr = arr + [...](它在時間和空間上也都非常高效)。第一個對列表對象進行了變更,後者創建了一個新的列表對象,並將其引用存儲在局部變量中(而不是更新傳入的變量以引用新對象,就像pass-引用)。