python 循环 for i in range(n) 超出指定限制 n

python loop for i in range(n) exceeding specified limit n

我正在尝试调试合并排序程序中的合并方法。方法如下:

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.

Python 向您显示 for k in range(n) 在它执行 之前。所以 k 仍然绑定到最后一个触摸它的命令的结果:

k += len(leftarray[i:])

您需要打印 k 之后 for 循环已将 range(n) 系列中的下一个值分配给 k.

要通过注释您的调试步骤来进一步说明这一点:

  1. > /home/**/Documents/**/**/merge_sort.py(36)merge()
    -> elif j == len(rightarray):
    

    k 未受影响,仍设置为 for k in range(n) 设置的值。

    (Pdb) n
    

    您现在执行了 j == len(rightarray) 测试并且发现它是正确的,因此您将进入:

  2. > /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,替换了之前绑定的任何值。

  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) 序列中的下一个值。

  4. > /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

这是 for-range 习语的一个有趣陷阱:它不是 C for 循环。循环将 运行 n 次,值 k=0 到 n-1,无论 k 在循环体中如何修改。如果您想模拟 C 风格的 for 循环(您可以通过更改循环变量提前终止),请改用 while 循环。