我正在尝试在合并排序的程序中调试合并方法。这是方法:
def merge(self, leftarray, rightarray):
n = len(leftarray) + len(rightarray)
print "len(leftarray) = "+str(len(leftarray))
print "len(rightarray) = "+str(len(rightarray))
i = 0
j = 0
merged = []
for k in range(n):
if i == len(leftarray):
merged.extend(rightarray[j:])
k += len(rightarray[j:])
elif j == len(rightarray):
merged.extend(leftarray[i:])
k += len(leftarray[i:])
elif leftarray[i] <= rightarray[j]:
merged.append(leftarray[i])
i += 1
elif leftarray[i] > rightarray[j] :
merged.append(rightarray[j])
j += 1
return merged
for k in range(n)
是表现出问题的循环。
这是调试器跟踪:
> /home/**/Documents/**/**/merge_sort.py(36)merge()
-> elif j == len(rightarray):
(Pdb) n
> /home/**/Documents/**/**/merge_sort.py(37)merge()
-> merged.extend(leftarray[i:])
(Pdb) n
> /home/**/Documents/**/**/merge_sort.py(39)merge()
-> k += len(leftarray[i:])
(Pdb) n
> /home/**/Documents/**/**/merge_sort.py(30)merge()
-> for k in range(n):
(Pdb) p k
3
(Pdb) n
> /home/**/Documents/**/**/merge_sort.py(31)merge()
-> if i == len(leftarray):
(Pdb) p n
3
(Pdb)
从跟踪中可以看出,n
的值为3,当k
为3时,执行不应进入循环。但执行转到行if i == len(leftarray):
而不是return merged
。
答案 0 :(得分:2)
Python会在for k in range(n)
行执行它之前向您显示 。所以k
仍然绑定到触及它的最后一个命令的结果:
k += len(leftarray[i:])
k
循环已将for
系列中的下一个值指定为range(n)
后,您需要打印k
。
通过注释调试步骤来解决这个问题:
> /home/**/Documents/**/**/merge_sort.py(36)merge()
-> elif j == len(rightarray):
k
未受影响且仍设置为for k in range(n)
设置的内容。
(Pdb) n
您现在执行了j == len(rightarray)
测试并且发现它是真的,所以您步入:
> /home/**/Documents/**/**/merge_sort.py(37)merge()
-> merged.extend(leftarray[i:])
(Pdb) n
> /home/**/Documents/**/**/merge_sort.py(39)merge()
-> k += len(leftarray[i:])
merged
已展开,您已走到k += len(leftarray[i:])
行。 k
仍然绑定到分配给它的循环的值。
(Pdb) n
您现在已执行k += len(leftarray[i:])
,k
现已设置为3
,取代之前绑定的任何值。
> /home/**/Documents/**/**/merge_sort.py(30)merge()
-> for k in range(n):
此行尚未执行,因此k
仍绑定到3:
(Pdb) p k
3
(Pdb) n
现在 k
不再是3
,它将成为range(n)
序列中的下一个值。
> /home/**/Documents/**/**/merge_sort.py(31)merge()
-> if i == len(leftarray):
(Pdb) p n
3
您现在需要再次测试k
;它将是1或2,具体取决于您在迭代过程中的位置。
for
循环在循环开始时确定迭代器 ;你为它提供了一个range()
序列,它将遵循你设置它的顺序。您无法更改k
并期望它不会被系列中的下一个值替换。
您可以使用while
循环代替:
k = 0
while k < n:
# do things, including altering k further
k += 1
答案 1 :(得分:2)
这是一个有趣的问题与范围成语:它不是一个C for循环。无论k在循环体中如何被修改,循环将以值k = 0到n-1运行n次。如果你想模拟一个C风格的循环(你可以通过改变循环变量来提前终止),那就改用一个while循环。