【问题标题】:Recursively generating lists of indices - Python递归生成索引列表 - Python
【发布时间】:2020-01-08 02:54:24
【问题描述】:

我正在尝试生成要用于以后分析的递增索引列表。虽然以下代码适用于生成 2 个索引的列表,但它不适用于任意数量的索引。这是生成 2 个递增索引列表的代码。

max_len = 9
idxs_len2 = [[idx1, idx2] for idx1 in range(1, max_len) for idx2 in range(idx1 + 1, max_len)]

例如,要生成三个递增索引的列表,我需要手动将代码更改为以下内容:

idxs_len3 = [
    [idx1, idx2, idx3] 
    for idx1 in range(1, max_len) 
    for idx2 in range(idx1 + 1, max_len) 
    for idx3 in range(idx2 + 1, max_len)
]

因此,目前,我无法为任意数量的索引生成递增索引列表。我想我可能需要创建一个递归函数来创建任意长度的索引列表。尽管我在网上找到了很多关于递归函数的信息,但我无法将该理论应用到我的特定用例中。到目前为止,我能想到的只有以下内容(没有产生所需的输出):

def generate_idxs(idx1, all_idxs, max_depth=3, max_len=9):
    current_idxs = []
    for idx2 in range(idx1 + 1, max_len):
        if len(current_idxs) < max_depth:
            current_idxs.append(idx2)
        else:
            all_idxs.append(current_idxs)
            generate_idxs(idx2, all_idxs, max_len=9)

# Calling the function
idxs_len3_test = []
generate_idxs(0, idxs_len3_test, max_len=9)
idxs_len3 == idxs_len3_test # ==> Yields False

有谁知道这个问题的答案,或者可以指出正确的方向吗?感谢您的宝贵时间,非常感谢。

最好, 凯文

编辑:谢谢大家的回答!我可能应该提到,生成一个元组列表也很好,它不一定需要是一个可以解决问题的递归函数。我只是认为只有使用递归函数才有可能,但我不知道我的问题也可以在没有递归函数的情况下解决。

【问题讨论】:

  • 您可以使用list(itertools.combinations(range(1, max_len), 3)) (将3 替换为任何内容。这会生成一个元组列表,但对于大多数用例来说应该没问题;另外,您可以随时将元组转换为列表,如果你想要的。
  • 非常容易实现并且可以满足我的需要。如果您将此评论作为答案发布,我会将其标记为已接受!

标签: python list recursion indices


【解决方案1】:

如果您专门寻找递归解决方案,那么这里有一种方法。

def generate_idxs(start, all_idxs, current_idxs, max_depth, max_len):
    if len(current_idxs) == max_depth:
        all_idxs.append(current_idxs.copy()) # Add the solution and return
        return
    for i in range(start + 1, max_len):
        current_idxs.append(i) # Add an element to the end
        generate_idxs(i, all_idxs, current_idxs, max_depth, max_len) # Recurse
        current_idxs.pop() # Remove the element at end (Backtrack)
    return

all_idxs = []
generate_idxs(0, all_idxs, [], 4, 6)
print(all_idxs)

输出

[[1, 2, 3, 4], [1, 2, 3, 5], [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]]

【讨论】:

    【解决方案2】:

    @iz_ 的 itertools.combinations() 解决方案似乎是最好的 (+1)。但是如果我要递归地写这个,我会想重入地做,没有副作用:

    def generate_idxs(max_depth, max_index, start=1):
        if start < max_index:
    
            if max_depth == 1:
                return [[index] for index in range(start, max_index)]
    
            return [[start, *index] for index in generate_idxs(max_depth - 1, max_index, start + 1)] + generate_idxs(max_depth, max_index, start + 1)
    
        return []
    
    print(generate_idxs(4, 6))
    

    输出

    > python3 test.py
    [[1, 2, 3, 4], [1, 2, 3, 5], [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]]
    >
    

    可以轻松修改代码以生成元组列表。

    【讨论】:

      猜你喜欢
      • 2021-01-06
      • 2021-01-05
      • 2013-06-30
      • 2019-04-22
      • 2017-03-26
      • 2021-10-17
      • 1970-01-01
      • 2021-05-22
      • 2016-05-03
      相关资源
      最近更新 更多