前一段时间,当我遇到这种奇怪的行为时,我一直在测试几种不同的python排序算法。
使用合并排序实现copied from GeeksforGeeks,我注意到我的Numpy数组被数组中的最后一个元素覆盖,而内置Python数组却被正确排序。
此行为的原因是什么?我有一种直觉,它是由引用传递vs值传递错误引起的,但是我不能完全确定原因是什么,因为它适用于内置的python数组。 / p>
注意:此行为也发生在某些其他算法上,而不仅仅是合并排序。
以下是可重现的示例:
import numpy as np
def mergeSort(arr):
if len(arr) >1:
mid = len(arr)//2 #Finding the mid of the array
L = arr[:mid] # Dividing the array elements
R = arr[mid:] # into 2 halves
mergeSort(L) # Sorting the first half
mergeSort(R) # Sorting the second half
i = j = k = 0
# Copy data to temp arrays L[] and R[]
while i < len(L) and j < len(R):
if L[i] < R[j]:
# print (arr, L, R)
arr[k] = L[i]
# print (arr, L, R)
i+=1
else:
# print (arr, L, R)
arr[k] = R[j] # Problem happens here, R replaces L and messes up calculations for numpy
# print (arr, L, R)
j+=1
k+=1
# Checking if any element was left
while i < len(L):
arr[k] = L[i]
i+=1
k+=1
while j < len(R):
arr[k] = R[j]
j+=1
k+=1
array = ([1,2,3,0])
print (f'python array before {array}')
mergeSort(array)
print (f'python array after {array}')
print ('----------')
array = np.array([1,2,3,0])
print (f'numpy array before {array}')
mergeSort(array)
print (f'numpy array after {array}')
这是控制台输出:
python array before [1, 2, 3, 0]
python array after [0, 1, 2, 3]
----------
numpy array before [1 2 3 0]
numpy array after [0 0 0 0]
我将覆盖的位置缩小到该行:
arr[k] = R[j]
您可以取消注释打印语句,并查看覆盖情况:
python array before [1, 2, 3, 0]
[1, 2] [1] [2]
[1, 2] [1] [2]
[3, 0] [3] [0] <-- Before arr[k] = R[j]
[0, 0] [3] [0] <-- After arr[k] = R[j] -- OK
[1, 2, 3, 0] [1, 2] [0, 3]
[0, 2, 3, 0] [1, 2] [0, 3]
[0, 2, 3, 0] [1, 2] [0, 3]
[0, 1, 3, 0] [1, 2] [0, 3]
[0, 1, 3, 0] [1, 2] [0, 3]
[0, 1, 2, 0] [1, 2] [0, 3]
python array after [0, 1, 2, 3]
----------
numpy array before [1 2 3 0]
[1 2] [1] [2]
[1 2] [1] [2]
[3 0] [3] [0] <-- Before arr[k] = R[j]
[0 0] [0] [0] <-- After arr[k] = R[j] -- BAD
[1 2 0 0] [1 2] [0 0]
[0 2 0 0] [0 2] [0 0]
[0 2 0 0] [0 2] [0 0]
[0 0 0 0] [0 0] [0 0]
numpy array after [0 0 0 0]
转载于:
Python 3.8.3 + Numpy 1.19.0
Jupyter Notebook 5.7.9 + Python 3.6.5 + Numpy 1.14.3