Python For循环包括范围的末尾

Python For循环包括范围的末尾,python,range,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的最小值是225。所以我们选择45 我已经创建了一个对整数进行因式分解的递归函数,我将factoredList传递到另一个名为groupIt的递归函数中,以找到最小的

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

给你一个两位数或更多的数字N。对于这个任务,你应该找到X的最小正数,这样它的数字乘积等于N。如果X不存在,那么返回0。 让我们来看看这个例子。N=20。我们可以将这个数字分解为2*10,但10不是一个数字。我们也可以将其分解为4*5或2*2*5。2*2*5的最小值是225,4*5-45的最小值是225。所以我们选择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时,lendigits-1=1,所以z的范围是0,1

据我所知,z应该只为0,因为它不会包含范围中的最后一个整数,但在[4,5]的相同for循环中,z最终会变为1

如果我将range0中的for z,lendigits-1替换为range0,1中的for z,那么代码可以工作,因此问题似乎确实存在


想法?

您的问题是,当您尝试使用.pop对其进行迭代以传递到递归调用时,正在对数字进行变异-错误不在递归调用中,而是当您返回到外部调用并尝试移动到下一个z时。您应该复制数字,例如使用数字[:],并改为:

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)
现在,递归调用忽略返回值,允许将最终完整输出的最小值返回给最初被称为groupIt的对象

例如,我得到:

>>> groupIt([2, 2, 3, 5])
256
返回前,输出==[345345256 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)

请考虑在数字中使用数字的首选项:而不是在Range0中的Z,LeNigigs-1:如果我只想迭代LeDigIts-1,这是否有效?当我尝试用一个GUTITY‘20'来运行你的代码时,我得到了一个类型错误:如果数字[Z] *数字[Z+1]>10,就不能用“STR”类型的非int乘以序列。您需要使用groupIt[2,2,5]运行它。我有一个单独的,未包含的函数,将20分解为[2,2,5]。啊,我必须小心我的变异。谢谢没问题。我刚刚添加了相同逻辑的更简洁版本。