2011-02-15 56 views
1

这是我在Wikipedia上发现的Python中Quicksort的源代码。关于变量作用域规则的Python问题

def pivot(v, left, right): 
    i = left 
    for j in range(left + 1, right + 1): 
     if v[j] < v[left]: 
      i += 1 # .. incrementa-se i 
      v[i], v[j] = v[j], v[i] 
    v[i], v[left] = v[left], v[i] 
    return i 

def qsort(v, left, right): 
    if right > left: 
     r = pivot(v, left, right) 
     qsort(v, left, r - 1) 
     qsort(v, r + 1, right) 

a = [4,2,4,6,3,2,5,1,3] 
qsort(a, 0, len(a)-1) 
print a # prints [1, 2, 2, 3, 3, 4, 4, 5, 6] 

我的问题是关于范围。当我通过a作为上述示例中的一个参数时,如果函数qsort可能将变量a更改为全局范围,如果它不“调用”'global a'?我一直在python编程1年,最近开始学习C.看起来我正在做一些混淆。 感谢

回答

6

它不重新绑定a/v,它只是变异它。如果您要改变绑定的对象,则不需要声明名称global

+2

这里重要的是`a`必须是一个可变类。如果`a`是一个不可变的类(即一个元组),它不起作用。 – 2011-02-15 19:05:47

+0

没错。似乎我将不得不再次学习Python。谢谢。 – FRD 2011-02-15 19:11:21

2

在python a通过“别名”(见下面的Jochen的评论)。因此,对v的任何修改将在a中重新列出。

编辑:我修正了我的措辞,感谢下面的评论。

0

qsort接收到也绑定到a的列表对象的引用。在该功能中,同一对象绑定到局部变量v,因此通过v所做的任何修改都会影响a

阅读关于对象,引用和变量的更多信息。

0

是的,rebind答案是一个很好的答案。您可能会感兴趣 - 自从您启动C以来,您可能需要熟悉拨打电话的呼叫请参考。也许知道那些提前将保护您免受意外:

void callByValue(int number) { 
    number = number + 1; 
} 

void callByReference(int *pnumber) { 
    *pnumber = *pnumber + 1; 
} 

void main() { 
    int x = 5; 
    callByValue(x); 
    // here, x is still 5 

    int y = 5; 
    callByReference(*y); 
    // here, y is now 6. 
} 

无论是因为它可能会,也用C你会发现,这些参数数量pnumber绑定到实际变量xy来自外界。在Python中,事实上,你有一个列表a = [4,2,4,6,3,2,5,1,3]将让你改变a之外的内部名称v。就像pnumber允许你在C.比较元组不会是可变的,将被复制,即a = (4,2,4,6,3,2,5,1,3)不会工作。就像在C number只是一个复制x - 因此x不改变以外。顺便说一下,我建议你跳过C,但是直接去找一些C++吧。有些事情在那里更好。例如,你可以在这里做不*pnumber所有的时间:

void callByReferenceCPlusPlus(int &number) { 
    number = number + 1; 
} 

void main() { 
    int z = 5; 
    callByReferenceCPlusPlus(z); 
    // hooray, z is 6! 
} 

这可能是口味的问题,但它确实是更直接,没有指针,细节想所有的时间。真。