使用Python生成列表组合 - 带规则

3

我有两个列表:

list1 = ["A", "B", "C", "D", "E"]
list2 = ["AA", "BB", "CC", "DD", "EE"]

我希望创建以下所有可能的组合:
    A-B-C-D-E
    A-BB-C-D-E
    A-B-C-DD-E...etc.

规则是相似的两个字母(如A-AA,B-BB)不能同时出现在组合中,并且顺序是可逆的(A-B-C-D-E和B-A-E-C-D在内容上是相同的,所以我不需要它们都出现)。

我该如何使用itertools来管理它?


我不确定我理解你的要求。如果我正确理解了,您想要给定两个长度为 N 的列表 ab,创建 N 个长度为 N 的列表,使得第 i 个列表是 a 列表的副本,但将第 i 个条目替换为列表 b 的第 i 个条目?省略 AA-B-C-D-EA-B-CC-D-E 是有意的吗? - Brian61354270
A-BB-CC-D-E” 可以在输出中吗?您的示例输出让我认为对于给定项,最多只允许一个两个字符列表项。 - ThePyGuy
1个回答

7
TL;DR: 使用itertools相对来说比较简单,但您必须仔细考虑每个步骤。
首先,您可以将两个列表进行zip操作,以获得元组序列。最终结果中的每个元素都将包括每个元组中恰好一个选项。然后,使用'-'.join函数将每个元组中的所有元素连接起来,并使用map函数将此过程应用到整个序列上。
>>> list1 = ["A", "B", "C", "D", "E"]
>>> list2 = ["AA", "BB", "CC", "DD", "EE"]
>>> list(zip(list1, list2))
[('A', 'AA'), ('B', 'BB'), ('C', 'CC'), ('D', 'DD'), ('E', 'EE')]

接下来,我们需要对这五个元组进行笛卡尔积运算。这将为我们提供32种不同的选择方式:先从A或AA中选择一个,然后从B或BB中选择一个,以此类推。要完成这个操作,我们使用* 来解压 zip 的结果,然后将其作为五个单独参数传递给product函数。

>>> from itertools import product
>>> for x in product(*zip(list1, list2)):
...   print(x)
...
('A', 'B', 'C', 'D', 'E')
('A', 'B', 'C', 'D', 'EE')
('A', 'B', 'C', 'DD', 'E')
('A', 'B', 'C', 'DD', 'EE')
('A', 'B', 'CC', 'D', 'E')
('A', 'B', 'CC', 'D', 'EE')
('A', 'B', 'CC', 'DD', 'E')
# etc

当您拥有产品时,产品中的每个元素都是'-'.join的有效参数之一,可创建您所需集合中的一个字符串:

>>> for x in map('-'.join, product(*zip(list1, list2))):
...   print(x)
...
A-B-C-D-E
A-B-C-D-EE
A-B-C-DD-E
A-B-C-DD-EE
A-B-CC-D-E
A-B-CC-D-EE
A-B-CC-DD-E
A-B-CC-DD-EE
A-BB-C-D-E
A-BB-C-D-EE
A-BB-C-DD-E
A-BB-C-DD-EE
A-BB-CC-D-E
A-BB-CC-D-EE
A-BB-CC-DD-E
A-BB-CC-DD-EE
AA-B-C-D-E
AA-B-C-D-EE
AA-B-C-DD-E
AA-B-C-DD-EE
AA-B-CC-D-E
AA-B-CC-D-EE
AA-B-CC-DD-E
AA-B-CC-DD-EE
AA-BB-C-D-E
AA-BB-C-D-EE
AA-BB-C-DD-E
AA-BB-C-DD-EE
AA-BB-CC-D-E
AA-BB-CC-D-EE
AA-BB-CC-DD-E
AA-BB-CC-DD-EE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接