如何在 Python 中创建多个 for 循环列表的递归以获得组合? [复制]
Posted
技术标签:
【中文标题】如何在 Python 中创建多个 for 循环列表的递归以获得组合? [复制]【英文标题】:How do I create a recursion of multiple for loops of lists in Python to get combination? [duplicate] 【发布时间】:2014-03-14 13:23:54 【问题描述】:我目前正在使用 python 来执行我的代码。我对这个函数的输入是一个列表中的一个列表,如[ [1,2,3],[4,5],[6,7,8,9] ]
目标是迭代并为每个列表创建所有可能的组合。
我想到的唯一方法是在主列表中的每个子列表上执行多个 for 循环。每个组合必须具有每个子列表中的至少一个元素,因此由于有 3 个子列表,因此所有组合必须具有 3 个元素。
for a in [1,2,3]:
for b in [4,5]:
for c in [6,7,8,9]:
l.append([a,b,c])
所以一种组合是 [1,4,6],[1,4,7],[1,4,8],[1,4,9]。下一个循环是 [1,5,6]..[1,5,7]...等等。
这可行,但我的问题是我不知道主列表(输入)中有多少子列表,所以我不能无限期地继续编写循环。我知道必须有一种方法可以编写递归函数,但我从未这样做过,也不知道它是如何工作的。我认为这应该不会太难,但有人可以告诉我完成此任务的算法吗?
非常感谢!!
【问题讨论】:
@Allen Lee 我认为这是一个重复的问题,除非您的情况不能使用 stdlib。 为什么这些问题仍然得到解答?这将有数百个重复。答案总是只使用 itertools。一个简单的谷歌搜索“python 组合”将为您提供指向 itertools 文档的链接作为第一个链接。然后 5-10 个链接到 SO 和解决方案。 【参考方案1】:如果您正在尝试学习递归,请这样想:所有列表的组合包括从第一个列表中一次获取一个项目,并将该项目添加到其余列表的所有组合中。
这样你就得到了
def combinations(rest, prefix = [], result = []):
if rest:
first = rest.pop()
for item in first:
prefix.append(item)
combinations(rest, prefix, result)
prefix.pop()
rest.append(first)
else:
result.append(list(reversed(prefix)))
return result
注意,我远非 Python 专家。可能有一种更优雅的方式来编码。请注意,因为我在列表的末尾推送和弹出,所以我需要反转最终结果。这样做的好处是速度快,不会产生垃圾。
空闲:
>>> combinations([ [1,2,3],[4,5],[6,7,8,9] ] )
[[1, 4, 6], [2, 4, 6], [3, 4, 6], [1, 5, 6], [2, 5, 6], [3, 5, 6],
[1, 4, 7], [2, 4, 7], [3, 4, 7], [1, 5, 7], [2, 5, 7], [3, 5, 7],
[1, 4, 8], [2, 4, 8], [3, 4, 8], [1, 5, 8], [2, 5, 8], [3, 5, 8],
[1, 4, 9], [2, 4, 9], [3, 4, 9], [1, 5, 9], [2, 5, 9], [3, 5, 9]]
【讨论】:
【参考方案2】:尝试使用itertools
库:
import itertools
arr = [[1,2], [3,4], [5,6]]
list(itertools.product(*arr))
# => [(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]
【讨论】:
以上是关于如何在 Python 中创建多个 for 循环列表的递归以获得组合? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
使用pytorch时使用for循环在python中创建self属性
Python:试图从一个寻找可被 3 整除的数字的 for 循环中创建一个逗号分隔的列表