绕过条件

时间:2016-08-20 08:57:26

标签: python python-3.x if-statement while-loop

有人能理解为什么以下代码失败了吗?

def main(A):
    A.sort()
    B = A[:]
    ll = len(B)
    while ll > 1:
        for i in range(ll):
            for n in range(i + 1, ll):
                 if (B[i] + B[n]) % 2 == 0:
                    B.remove(B[n])
                    B.remove(B[i])
                    main(B)
    return B
if __name__ == '__main__':
    result = main([4, 5, 3, 7, 2])
    print(result)

它运行正常,直到我的列表只有一个值,到达"返回B"声明,然后它再次跳回到循环中。我错过了什么?

1 个答案:

答案 0 :(得分:1)

您正在使用递归,在循环中再次调用main(B)。当递归调用返回时,您从中调用它的循环继续

此外,您忽略递归调用的返回值。由于您在main()的每次调用中使用列表的副本,忽略返回值意味着您放弃递归调用所做的所有工作。

最后但并非最不重要的是,您要删除B中的元素;您的循环会遇到索引错误,因为in范围都是ll,这个长度在删除元素后不再有效。因为您无法更新正在循环的range()对象;您必须使用while循环来测试每次迭代的长度:

i = 0
while i < len(B):
    n = i + 1
    while n < len(B):
        if (B[i] + B[n]) % 2 == 0:
            del B[n], B[i]
            break
        else:
            n += 1
    else:
        i += 1

上面的循环将从列表中删除总和为偶数的任何两个数字。请注意,当您同时删除ni值时,可以使用索引,而不是使用list.remove()搜索该数字。

内部while循环使用else套件;这只有当你没有突破循环时才会执行,只有在我们没有删除索引i的值时才会执行此操作。因此,当您没有找到B[i]的配对时,i会增加以继续前进到下一个候选人。如果你找到一个配对, the value at i is deleted, so now B [i]`已经引用了下一个值。

我不确定为什么你需要在这个循环之后递归;由于您已经测试了每个组合,因此递归调用无法找到更多此类配对。

演示,使用sorted()添加复制:

>>> def main(A):
...     B = sorted(A)
...     i = 0
...     while i < len(B):
...         n = i + 1
...         while n < len(B):
...             if (B[i] + B[n]) % 2 == 0:
...                 del B[n], B[i]
...                 break
...             else:
...                 n += 1
...         else:
...             i += 1
...     return B
...
>>> main([4, 5, 3, 7, 2])
[7]