【问题标题】:How to limit Python recursive combinations?如何限制 Python 递归组合?
【发布时间】:2014-11-16 23:41:23
【问题描述】:

我目前正在尝试解决如何让这段代码遍历下面的不同数字组合以等于 1200。这工作正常但是我希望代码限制它探索的数字并使用 只有 5 个不同的数字。

E.g1 70、260、280、290、300 = 1200,使用 5 个数字。我只想要这些组合。

例如 10、20、30、40、110、120、160、190、240、280 = 1200,使用 10 个数字。我不想要小于 5 或​​大于 5 的组合,比如这种组合。

我不太了解python,我觉得它是一件简单的事情,但我的编码知识有限。

#!/usr/local/bin/python
from itertools import combinations

def find_sum_in_list(numbers, target):
    results = []
    for x in range(len(numbers)):
        results.extend(
            [   
                combo for combo in combinations(numbers ,x)  
                    if sum(combo) == target    
            ]
    )
    print results

if __name__ == "__main__":
    find_sum_in_list([10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300], 1200)

感谢您的帮助。非常感谢。

【问题讨论】:

  • 两件事:1)我看不出你的函数是如何递归的。它不调用自己。 2)如果你只想要5个元素的组合,为什么要循环x的不同值并要求x元素的组合?
  • 对不起,这种数学超出了我的范围。我尝试将 5 放入 x 中,它确实有效。在我看到我的错误之前,我需要有人指出我。谢谢。

标签: python recursion limit combinations


【解决方案1】:

我认为combinations 第二个参数是要组合的项目数。尝试传递 5 而不是 x

【讨论】:

    【解决方案2】:

    实际上,您几乎拥有所需的一切。正如@Eric 所说,列表理解中的两行几乎是所有内容,除了使用“5”而不是“x”。如果您使用过滤器清除所有总和不正确的组合,那么您最终会得到:

    from itertools import combinations
    
    def find_sum_in_list(numbers, target):
        return filter(lambda x: sum(x) == target, combinations(numbers, 5))
    
    if __name__ == '__main__':
        print find_sum_in_list(range(10, 310, 10), 1200)
    

    filter 接受一个函数,该函数接受列表的每个元素并返回 true 或 false。我已将一个匿名函数传递给它,该函数仅在列表总和为目标时才返回 true。

    我还使用 range 来生成你的数字列表,从 10 到 310 x 10 计数。range 不包括最后一个元素。

    【讨论】:

    • 这是一个聪明的方法,谢谢。但是,我想运行其他数字组合,其中一些数字重复,因此可能有两个 10 或三个 30。我认为我不能用这种方法作为一个范围而不是离散数字来做到这一点。
    • 不客气。不过,您可以使用这个 find_sum_in_list 实现。这不是我使用范围所特有的。
    • 对不起我的错误:P。我没有仔细阅读您的代码。
    【解决方案3】:

    你在正确的轨道上,但我认为你不需要做一些递归的事情。我认为这行得通。

    from itertools import combinations
    
    def find_sum_in_list(numbers, target, comboSize):
        results = []
        for combo in combinations(numbers, comboSize):
            if sum(combo) == target:
                results.append(combo)
        return results
    
    
    if __name__ == "__main__":
        numbers = [10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300]
        total = 1200
        comboSize = 5
        print find_sum_in_list(numbers, total, comboSize)
    

    【讨论】:

    • 感谢这个代码看起来也不错。你写的也很清楚,所以我更容易理解。
    • @Metori 没问题。你绝对可以用像杰克这样的答案来简短地说,但这听起来很重要,这是可以理解的。不要忘记为您喜欢和接受的答案投票。
    • 这个解决方案的唯一问题是 main 块中的额外循环。他只需要五个数字组合,这给了他更多。
    【解决方案4】:

    嗯,它的递归性不亚于您的代码,但我认为它可以满足您的需求。

    import itertools
    
    target_list = [
        10, 20, 30, 40, 50, 60, 70, 80, 
        90, 100, 110, 120, 130, 140, 150, 
        160, 170, 180, 190, 200, 210, 220, 
        230, 240, 250, 260, 270, 280, 290, 300
    ]
    
    target_sum = 1200
    
    def find_sum(target_list, num_elem, target_sum):
        combinations = itertools.combinations(target_list, num_elem)
    
        for comb in combinations:
            if sum(comb) == target_sum:
                print comb
    
    
    find_sum(target_list, 5, target_sum)
    

    【讨论】:

    • 我也很喜欢你的方法。吐出组合似乎非常快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2012-01-17
    • 2019-03-12
    • 2018-06-25
    • 2014-09-13
    • 2014-08-04
    相关资源
    最近更新 更多