Python 如何找到指定范围内的一个数字列表与另一个数字之和?

Python 如何找到指定范围内的一个数字列表与另一个数字之和?,python,Python,使用Python 以下是一些要求: 我想找到一个编号[]的列表: 把数字加起来(比如说30) 在(开始,结束)的范围内,比如说(8,20) 列表中有Y(比如3)个元素 例:[8,10,12] 我已经尝试了下面的代码,这是我想要的,但它给了我所有的组合,这是非常沉重的记忆。为了选择一个,我只是随机选择了一个,但是我想用它来处理更大范围的列表,所以这是没有效率的 list(combinations(list(range(8,20)),3)) 您发布的代码没有检查金额 以下代码段优化内存使用,而不是

使用Python

以下是一些要求:

我想找到一个编号[]的列表:

  • 把数字加起来(比如说30)

  • 在(开始,结束)的范围内,比如说(8,20)

  • 列表中有Y(比如3)个元素

  • 例:[8,10,12]

    我已经尝试了下面的代码,这是我想要的,但它给了我所有的组合,这是非常沉重的记忆。为了选择一个,我只是随机选择了一个,但是我想用它来处理更大范围的列表,所以这是没有效率的

    list(combinations(list(range(8,20)),3))
    

    您发布的代码没有检查金额

    以下代码段优化内存使用,而不是运行时

    如果您使用的是Python 3,那么
    组合
    已经返回了一个生成器。你所要做的就是迭代这些组合。如果总和正确,则从循环中打印组合和
    break

    from itertools import combinations
    
    for comb in combinations(range(8, 20), 3):
        if sum(comb) == 30:
            print(comb)
            break
    
    输出

    (8, 9, 13)
    
    (8, 9, 13)
    (8, 10, 12)
    (9, 10, 11)
    
    (8, 9, 13)
    (8, 10, 12)
    (9, 10, 11)
    
    或者,您可以使用
    filter
    ,然后对结果调用
    next
    。这样,您可以获得任意数量的组合:

    from itertools import combinations
    
    valid_combs = filter(lambda c: sum(c) == 30, combinations(range(8, 20), 3))
    
    print(next(valid_combs))
    print(next(valid_combs))
    print(next(valid_combs))
    
    输出

    (8, 9, 13)
    
    (8, 9, 13)
    (8, 10, 12)
    (9, 10, 11)
    
    (8, 9, 13)
    (8, 10, 12)
    (9, 10, 11)
    
    一个更高级、更动态的解决方案是使用一个函数,并从中获得收益(如果您使用的是Python>=3.3):

    输出

    (8, 9, 13)
    
    (8, 9, 13)
    (8, 10, 12)
    (9, 10, 11)
    
    (8, 9, 13)
    (8, 10, 12)
    (9, 10, 11)
    

    下面是一个递归函数的示例,可以有效地执行此操作

    def rangeToSum(start,stop,target,count):
        if count == 0: return []
        minSum = sum(range(start,start+count-1))
        stop   = min(stop,target+1-minSum)
        if count == 1 :
            return [target] if target in range(start,stop) else [] 
        for n in reversed(range(start,stop)):
            subSum = rangeToSum(start,n,target-n,count-1)
            if subSum: return subSum+[n]
        return []
    
    print(rangeToSum(8,20,30,3)) # [8,10,12]
    
    它的工作方式是先尝试最大的数字,然后调用自身,在剩余范围内查找与剩余值相加的数字。这将跳过无法生成目标和的整个组合线束。e、 在包含19、18、16、15、14、13、12或11的组合上尝试20次跳跃

    它还考虑了第一个count-1项目将产生的最小总和,以进一步降低停止值。e、 g.从8到30,3个数字将至少使用17(8+9)作为前两个数字,因此范围的停止值可以减少到14,因为17+13将达到30,任何更高的值都将超过30

    对于较大的数字,函数在大多数情况下会很快找到解决方案,但也可能需要很长时间,具体取决于参数的组合

     rangeToSum(80000,20000000,3000000,10) # 0.6 second
    
     # [80000, 80002, 80004, 80006, 80008, 80010, 80012, 80014, 80016, 2279928]
    
    如果您需要更快,可以尝试记忆(例如,使用functools中的lru_缓存)