Python For Loop包含范围的结尾

时间:2014-03-11 16:28:40

标签: python range

我在checkio.org上试图解决这个问题:

您将获得两位或更多位数字N.对于此任务,您应找到最小的正数X,使其数字的乘积等于N.如果X不存在,则返回0。 让我们来看看这个例子。 N = 20.我们可以将此数字分解为2 * 10,但10不是数字。我们也可以将其分解为4 * 5或2 * 2 * 5。 2 * 2 * 5的最小数字是225,对于4 * 5 - 45.所以我们选择45。

我创建了一个递归函数,它将一个整数分解,我将factoredList传递给另一个名为" groupIt"的递归函数。找到最小整数,它是因子整数的乘积。

这里的功能是:

def groupIt(digits):
    tempList = []
    if len(digits)>1:
        for z in range(0,len(digits)-1):
            if digits[z]*digits[z+1]>=10:
                toStore=""
                for k in range(0,len(digits)):
                    toStore+=str(digits[k])
                return int(toStore)
            else:
                digits.append(digits.pop(z+1)*digits.pop(z))
                digits.sort()
                tempList.append(groupIt(digits))
    else:
        return digits[0]
    tempList.sort()
    return tempList[0]

对于一个整数' 20',因式列表是2 x 2 x 5.当我在[4,5]上递归调用groupIt时," len(数字)-1" = 1,所以z从范围(0,1)开始。

根据我的理解,z应该只是0,因为它不会包含范围中的最后一个整数,但是z最终会在[4,5]的相同for循环中变为1。 / p>

如果我替换"对于范围内的z(0,len(数字)-1)"用"表示范围(0,1),"代码工作,所以问题确实在那里被隔离。

思想?

1 个答案:

答案 0 :(得分:2)

您的问题是,当您尝试迭代它(使用digits)传递给递归调用时,您正在变异.pop - 错误不在递归调用中,它& #39;当你回到外线电话并尝试移动到下一个z时。你应该制作一个副本数字(例如使用digits[:])并改为改为:

else:
    digits_mod = digits[:]
    digits_mod.append(digits_mod.pop(z+1) * digits_mod.pop(z))
    digits_mod.sort()
    tempList.append(groupIt(digits_mod))

但是,此修改仍然不允许代码适用于例如groupIt([2, 2, 3, 5]),返回2235而不是256

相反。我建议在顶层制作一个列表并将其传递下去,允许在所有级别进行修改:

def groupIt(digits, output=None):
    if output is None:
        output = []
    if len(digits)>1:
        for z in range(0,len(digits)-1):
            if digits[z]*digits[z+1]>=10:
                toStore=""
                for k in range(0,len(digits)):
                    toStore+=str(digits[k])
                output.append(int(toStore)) # note storage here
            else:
                digits_mod = digits[:]
                digits_mod.append(digits_mod.pop(z+1) * digits_mod.pop(z))
                digits_mod.sort()
                groupIt(digits_mod, output) # note call here
    else:
        return digits[0] # still need this for single digit case
    return min(output)

现在,递归调用忽略了return值,允许最终的完整output的最小值返回到首先调用groupIt的任何值。

我得到了,例如:

>>> groupIt([2, 2, 3, 5])
256

(返回前output == [345, 345, 256, 256, 2235])。


相同逻辑的更简洁版本:

def groupIt(lst, out=None):
    if out is None:
        out = set()
    out.add(int("".join(map(str, sorted(lst)))))
    if len(lst) > 1:
        for i in range(len(lst)-1):
            n = lst[i] * lst[i+1]
            if n < 10:
                groups(lst[:i] + [n] + lst[i+2:], out)
    return min(out)