2011-02-15 53 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! 
} 

這可能是口味的問題,但它確實是更直接,沒有指針,細節想所有的時間。真。