范围(n)中超出指定限制n的i的python循环

时间:2015-02-05 12:08:22

标签: python for-loop pdb

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

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

2 个答案:

答案 0 :(得分:2)

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,具体取决于您在迭代过程中的位置。

  5. 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循环。