2015-04-26 33 views
2

首先,我編寫了代碼的第一個示例,但它無法正常工作。我更喜歡第一個樣本,但只有第二個樣本正常工作。我不知道爲什麼第一個樣本沒有改變原始數組,但是第二個樣本沒有改變。區別在哪裏?函數中的引用如何工作?

首先樣品:

import heapq 

def heap_sort(tab): 
    heap = [] 
    for i in tab: 
     heapq.heappush(heap, i) 
    tab = [heapq.heappop(heap) for _ in xrange(len(heap))] 

temp_tab = [4, 3, 5, 1] 
heap_sort(temp_tab) 
print temp_tab 

打印:

[4, 3, 5, 1] 

第二樣品:

import heapq 

def heap_sort(tab): 
    heap = [] 
    for i in tab: 
     heapq.heappush(heap, i) 
    for i, _ in enumerate(tab): 
     tab[i] = heapq.heappop(heap) 

temp_tab = [4, 3, 5, 1] 
heap_sort(temp_tab) 
print temp_tab 

個打印:

[1, 3, 4, 5] 
+2

在第一個例子,如果你已經分配給'標籤[:]'而不是'tab',它會起作用。 – Navith

+1

這段代碼有什麼意義?爲什麼不返回堆而不是將所有內容都推回到選項卡中?實際上,爲什麼不直接對列表進行排序並忘記堆內容呢? –

回答

3

你也可以使用[:],這將改變傳遞的原始對象:

def heap_sort(tab): 
    heap = [] 
    for i in tab: 
     heapq.heappush(heap, i) 
    tab[:] = [heapq.heappop(heap) for _ in xrange(len(heap))] 

因此,而不是重新分配名稱tab到一個新的對象,你實際上是更新原有tab對象。

你也可以使用一個發電機的表達,而不是建立一個完整的列表

tab[:] = (heapq.heappop(heap) for _ in xrange(len(heap))) 
2

因爲你只是重新分配了一個名爲tab在函數內部新的名稱,它不會影響tab你定義的全局名稱。 因此,改變你的函數實際上返回值,將工作:

import heapq 

def heap_sort(tab): 
    heap = [] 
    for i in tab: 
     heapq.heappush(heap, i) 
    # return the supposed tab value 
    return [heapq.heappop(heap) for _ in xrange(len(heap))] 

tab = [4, 3, 5, 1] 
# assign the tab to the returned value 
tab = heap_sort(tab) 
print tab 
[1, 3, 4, 5] 

供您參考,請閱讀How do I pass a variable by reference?將幫助您瞭解引用Python中是如何工作的。

+0

但是如果我有不同的名字(tab1),結果是一樣的。 – WuJo

+2

@WuJo,關鍵在於,在函數內部,他們無法訪問全局'tab',只是在函數返回時創建一個名爲'tab'的新名稱,新的'tab'值被丟棄。 – Anzel

+0

@WuJo,所以相反,你重新分配你的全局'tab'到函數返回的值,將會起作用。 – Anzel

-1

試試這個:

>>> def heap_sort(tab): 
    heap=[] 
    for i in tab: 
     heapq.heappush(heap,i) 
    heapq.heapify(heap) 
    return heap 

>>> t=heap_sort(t) 
>>> print(t) 
[1, 3, 5, 4]