【问题标题】:How can i add n nested for loops dynamically using recursion on this:如何使用递归动态添加 n 嵌套 for 循环:
【发布时间】:2020-08-19 16:51:20
【问题描述】:

我想动态添加 N 个嵌套 for 循环,如果可能,使用递归,在此代码上遵循此模式:

 Total = 4
 counter = 0
 for i in range(1, Total + 1):
     for j in range(i + 1, Total + 1):
         for k in range(j + 1, Total + 1):
             print(i, j ,k)
             counter += 1
 print(f"Number of combinations: {counter}")

输出将是总共4个数字(1、2、3、4)中3个数字的所有组合,按排序顺序排列,结果总和:

1 2 3
1 2 4
1 3 4
2 3 4
Number of combinations: 4

这是我的动机,我想动态增加组合的长度。

我喜欢Total choose N elements(其中 N 等于该模式中嵌套 for 循环的数量)之类的东西,我发现这样做的唯一方法是使用以前的模式对 N 个嵌套的 for 循环进行硬编码。

我已经尝试通过在stackoverflow 上提出的一些类似问题来自己实现这一点,但是我没有成功地使用递归和希望的模式创建for 循环,如果我想要itertools combinations 也不起作用类似于a combination of 15 elements(set of length 15) from 25 in total,如下所示:

#Adapted from https://www.geeksforgeeks.org/permutation-and-combination-in-python/
# A Python program to print all
# combinations of given length
from itertools import combinations
Total = 25
n = 15
counter = 0
# Get all combinations of [1,2,3..25]
# and length n
comb = combinations([i for i in range(1, Total + 1)], n)

# Print the obtained combinations
for i in list(comb):
    print(i)
    counter += 1
print(f"Number of combinations: {counter}")

预期输出:

               1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
               1 2 3 4 5 6 7 8 9 10 11 12 13 14 16
               1 2 3 4 5 6 7 8 9 10 11 12 13 14 17
                              ...
               10 12 13 14 15 16 17 18 19 20 21 22 23 24 25
               11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
               Number of combinations:  3.268.760

实际输出是:Killed,但是如果像下面这样的硬代码,它工作得很好,并给出了所需的输出:

def main():
    counter = 0
    for a in range (1, 26,1):
        for b in range (a + 1, 26,1):
            for c in range (b + 1, 26,1):
                for d in range (c + 1, 26,1):
                    for e in range (d + 1, 26,1):
                        for f in range (e + 1, 26,1):
                            for g in range (f + 1, 26,1):
                                for h in range (g + 1, 26,1):
                                    for i in range (h + 1, 26,1):
                                        for j in range (i + 1, 26,1):
                                            for k in range (j + 1, 26,1):
                                                for l in range (k + 1, 26,1):
                                                    for m in range (l + 1, 26,1):
                                                        for n in range (m + 1, 26,1):
                                                            for o in range (n + 1, 26,1):
                                                                print(a, b, c, d, e, f, g, h, i, j, k, l, m , n, o)
                                                                counter += 1
    print(f"Number of combinations: {counter}")
main()

但是,我不能根据需要扩展和收缩组合集。通过动态增加和减少嵌套 for 循环的数量来获得它会很好。 *感谢大家的反馈

【问题讨论】:

  • "itertools combinations" fails: 怎么会失败?
  • 其中有两个原因:如果我喜欢 25 选择 15,则程序不起作用 - 它在尖叫声中打印出被杀死 - 长度不仅仅是 15,它就像 1 到 15。如果我确实喜欢我展示了它的工作原理,但看起来编码很糟糕,而且不是动态的。
  • 您应该编辑您的问题以发布失败的程序、您的示例输入和您的预期输出,以获得正确的答案。我很难理解像if I do like 25 choose 15 the program do not work 这样的陈述。
  • 好的,谢谢,我会编辑的。

标签: python-3.x loops for-loop recursion combinatorics


【解决方案1】:

itertools.combinations 方法对我来说很好用。如果您在具有少量内存的虚拟机/docker 容器上运行它,您可能会遇到内存问题。 Python 整数占用 24 个字节,因此您至少需要 74.8MB (24 * 3268760) 的内存,加上存储列表的列表开销(大约 25MB)。

请注意,list(comb) 将尝试提前计算所有组合并会消耗内存。您一直在阅读的教程是错误的。您应该直接使用迭代器,即

...
for i in comb:
    print(i)
    counter += 1
print(f"Number of combinations: {counter}")

如果你只追求物品的数量,你可以使用这个技巧来让它更短:

counter = sum(1 for item in comb)
print(f"Number of combinations: {counter}")

【讨论】:

  • 老兄,效果很好,谢谢!没错,我正在虚拟机上运行我的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 2015-05-24
相关资源
最近更新 更多