2012-08-15 37 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-引用)。