當作為切片傳遞給 enumerate() 時,是否形成了新的陣列副本?這是我在運行以下實驗后的猜測。在我看來就是這樣,但我不確定如何用代碼證明我的想法?
下面是一個代碼片段和 2 個結果。選項 A 和選項 B 對應的結果也如下。
def selection_sort(arr):
# for idx, item in enumerate(arr[:-1]): # option A
for idx, item in enumerate(arr): # option B
curr_min = item
swap_ptr = idx
print('========================================')
print('curr_min: {}'.format(curr_min))
print('arr before: {}'.format(arr))
for j in range(idx 1, len(arr)):
print('for item {}'.format(arr[j]))
if arr[j] < curr_min:
print('{} < {}'.format(arr[j], curr_min))
curr_min = arr[j]
swap_ptr = j
print('swap_ptr now at {} pointing to {}'.format(swap_ptr, curr_min))
(arr[idx], arr[swap_ptr]) = (arr[swap_ptr], arr[idx])
print('arr after: {}'.format(arr))
return arr
print(selection_sort([5,9,1,3,0,20,77,46]))
在選項 A 上運行的結果(即,將選項 B 注釋掉):
========================================
curr_min: 5
arr before: [5, 9, 1, 3, 0, 20, 77, 46]
for item 9
for item 1
1 < 5
swap_ptr now at 2 pointing to 1
for item 3
for item 0
0 < 1
swap_ptr now at 4 pointing to 0
for item 20
for item 77
for item 46
arr after: [0, 9, 1, 3, 5, 20, 77, 46]
========================================
curr_min: 9
arr before: [0, 9, 1, 3, 5, 20, 77, 46]
for item 1
1 < 9
swap_ptr now at 2 pointing to 1
for item 3
for item 5
for item 20
for item 77
for item 46
arr after: [0, 1, 9, 3, 5, 20, 77, 46]
========================================
curr_min: 1
arr before: [0, 1, 9, 3, 5, 20, 77, 46]
for item 3
for item 5
for item 20
for item 77
for item 46
arr after: [0, 1, 9, 3, 5, 20, 77, 46]
========================================
curr_min: 3
arr before: [0, 1, 9, 3, 5, 20, 77, 46]
for item 5
for item 20
for item 77
for item 46
arr after: [0, 1, 9, 3, 5, 20, 77, 46]
========================================
curr_min: 0
arr before: [0, 1, 9, 3, 5, 20, 77, 46]
for item 20
for item 77
for item 46
arr after: [0, 1, 9, 3, 5, 20, 77, 46]
========================================
curr_min: 20
arr before: [0, 1, 9, 3, 5, 20, 77, 46]
for item 77
for item 46
arr after: [0, 1, 9, 3, 5, 20, 77, 46]
========================================
curr_min: 77
arr before: [0, 1, 9, 3, 5, 20, 77, 46]
for item 46
46 < 77
swap_ptr now at 7 pointing to 46
arr after: [0, 1, 9, 3, 5, 20, 46, 77]
[0, 1, 9, 3, 5, 20, 46, 77]
在選項 B 上運行的結果(即注釋掉選項 A):
========================================
curr_min: 5
arr before: [5, 9, 1, 3, 0, 20, 77, 46]
for item 9
for item 1
1 < 5
swap_ptr now at 2 pointing to 1
for item 3
for item 0
0 < 1
swap_ptr now at 4 pointing to 0
for item 20
for item 77
for item 46
arr after: [0, 9, 1, 3, 5, 20, 77, 46]
========================================
curr_min: 9
arr before: [0, 9, 1, 3, 5, 20, 77, 46]
for item 1
1 < 9
swap_ptr now at 2 pointing to 1
for item 3
for item 5
for item 20
for item 77
for item 46
arr after: [0, 1, 9, 3, 5, 20, 77, 46]
========================================
curr_min: 9
arr before: [0, 1, 9, 3, 5, 20, 77, 46]
for item 3
3 < 9
swap_ptr now at 3 pointing to 3
for item 5
for item 20
for item 77
for item 46
arr after: [0, 1, 3, 9, 5, 20, 77, 46]
========================================
curr_min: 9
arr before: [0, 1, 3, 9, 5, 20, 77, 46]
for item 5
5 < 9
swap_ptr now at 4 pointing to 5
for item 20
for item 77
for item 46
arr after: [0, 1, 3, 5, 9, 20, 77, 46]
========================================
curr_min: 9
arr before: [0, 1, 3, 5, 9, 20, 77, 46]
for item 20
for item 77
for item 46
arr after: [0, 1, 3, 5, 9, 20, 77, 46]
========================================
curr_min: 20
arr before: [0, 1, 3, 5, 9, 20, 77, 46]
for item 77
for item 46
arr after: [0, 1, 3, 5, 9, 20, 77, 46]
========================================
curr_min: 77
arr before: [0, 1, 3, 5, 9, 20, 77, 46]
for item 46
46 < 77
swap_ptr now at 7 pointing to 46
arr after: [0, 1, 3, 5, 9, 20, 46, 77]
========================================
curr_min: 77
arr before: [0, 1, 3, 5, 9, 20, 46, 77]
arr after: [0, 1, 3, 5, 9, 20, 46, 77]
[0, 1, 3, 5, 9, 20, 46, 77]
請告訴我如何證明我對這個奇怪現象的想法。似乎當陣列以切片方式傳遞給 enumerate() 時,它只會從函式引數串列中迭代“舊”陣列。但是當沒有任何切片傳遞時, enumerate() 會迭代在回圈中修改的新陣列。我不確定是否可以使用代碼和檔案而不是運行此實驗來證明這一點?為什么這個設計如此奇怪?TIA。
uj5u.com熱心網友回復:
我可以確認是這樣的。讓我們看看我的作業。
我首先創建一個基本串列:
foo = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
然后,當我們迭代列舉時,我將編輯其中一個值:
>>> once = True
>>> for idx, val in enumerate(foo):
... if once:
... once = False
... foo[2] = 666
... print(idx, val)
...
0 0
1 1
2 666
3 3
4 4
5 5
6 6
7 7
8 8
9 9
我們注意到列舉在達到它的索引時會顯示編輯值。
現在我們在傳遞切片而不是原始切片時做同樣的事情:
>>> foo = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> once = True
>>> for idx, val in enumerate(foo[:]):
... if once:
... once = False
... foo[2] = 42
... print(idx, val)
...
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
>>> foo
[0, 1, 42, 3, 4, 5, 6, 7, 8, 9]
我們看到雖然foo已經被編輯,但列舉并不知道更改,因為它必須使用原始的未修改副本。
我調查了為什么會這樣。當使用方括號表示法時,我們實際上是在呼叫slice 類。
這表示它回傳一個 Slice 物件。這顯然與您的原始串列不同。
如果您有興趣,您甚至可以在源代碼中查看物件創建。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/462159.html
