【问题标题】:Write a function that takes two natural numbers ???? and ???? as inputs and returns the set of all tuples of size ???? that sum to ????写一个接受两个自然数的函数????和 ????作为输入并返回所有大小为 ???? 的元组的集合那个总和???
【发布时间】:2020-05-25 11:27:38
【问题描述】:

在 python 3 中,我正在尝试编写一个需要两个自然数的函数 ????和 ????作为输入并返回所有大小为 ???? 的元组的集合总和是????。

我已经构建了以下函数:

def get_tuples(length, total):
    if length == 1:
        yield (total,)
        return


    for i in range(total + 1):
        for t in get_tuples(length - 1, total - i):
            yield (i,) + t

其中,例如,list(get_tuples(2, 8)) 返回正确的结果,并且:

 def get_tuples(length, total):
    if length == 1:
        return [(total,)]

    comp = []
    for i in range(total + 1):
        for t in get_tuples(length - 1, total - i):
            comp.append((i,) + t)
        return comp

但是返回错误的结果(即单个元组)。 谁能解释一下为什么,以及如何修复第二个功能?

【问题讨论】:

  • 元组包含正整数对吗?
  • 你有一个return 在循环中,所以它在第一次通过时退出。
  • @Tupteq 谢谢,如果没有生成器,我怎样才能使第二个函数工作?

标签: python combinatorics


【解决方案1】:

只需将 return 缩进一个:

def get_tuples(length, total):
    if length == 1:
        return [(total,)]

    comp = []
    for i in range(total + 1):
        for t in get_tuples(length - 1, total - i):
            comp.append((i,) + t)
    return comp

编辑:确保您了解原因

【讨论】:

  • 嘿,我读了,但我不明白为什么内部 for 循环带有对 get_tuples() 的递归调用,你能解释一下吗?
【解决方案2】:

owninggreendragsdude 的答案是正确的,因为它准确地显示了您需要在代码中更改以使其正常工作的一件事。

但是,如果您想知道如何摆脱递归并同时使代码更快,这里有一个解决方案:

def get_tuples_optimized(length, total):
    comp = []

    # Stack of partial tuples to process, initialized with an empty tuple
    todo = [(total, tuple())]

    # Loop as long as we have partial tuples on our stack
    while todo:
        # Take the next partial tuple
        amount_left, partial_tuple = todo.pop()

        if len(partial_tuple) == length - 1:
            # Put all that is left as the last element
            comp.append(partial_tuple + (amount_left,))
        else:
            # Add all possible extensions-by-one to our stack
            for i in range(amount_left + 1):
                extended_tuple = partial_tuple + (i,)
                todo.append((amount_left - i, extended_tuple))

    return comp

【讨论】:

    【解决方案3】:

    给你:

    def get_tuples(length, total):
    if length == 1:
        return [(total,)]
    
    comp = []
    
    for i in range(total + 1):
        for t in get_tuples(length - 1, total - i):
            comp.append((i,) + t)
    return comp
    

    将return语句从循环中取出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-18
      • 1970-01-01
      • 2022-08-02
      • 2022-11-15
      • 1970-01-01
      相关资源
      最近更新 更多