首页 > 解决方案 > 在 Python 中生成特定的列表组合

问题描述

我有 2 个不同长度的列表,比如:

list_a = ['a', 'b', 'c', 'd']
list_b = ['x', 'y']

我想要的输出是 list_b 到 list_a 的所有唯一组合,例如,应该有 16 个:

1. ['a', 'x', 'y']
2. [['a', 'x'], ['b', 'y']]
3. [['a', 'x'], ['c', 'y']]
4. [['a', 'x'], ['d', 'y']]
5. ['b', 'x', 'y']
6. [['b', 'x'], ['a', 'y']]
7. [['b', 'x'], ['c', 'y']]
8. [['b', 'x'], ['d', 'y']]
9. ['c', 'x', 'y']
10. [['c', 'x'], ['a', 'y']]
11. [['c', 'x'], ['b', 'y']]
12. [['c', 'x'], ['d', 'y']]
13. ['d', 'x', 'y']
14. [['d', 'x'], ['a', 'y']]
15. [['d', 'x'], ['b', 'y']]
16. [['d', 'x'], ['c', 'y']]

我对列表总数的猜测是 len(list_a) ** len(list_b),所以我知道选项空间很快就会变得非常大。

关于在 Python 中执行此操作的有效方法的任何建议(避免生成过多的排列和测试重复项等)/

我在许多不同的列表类型和组成中使用了 itertools 产品、排列和组合。我可以通过使用循环来查找所有答案,其中每个 list_a 有来自 list_b 的 2 个条目(即上面的 1、5、9、13),然后是每个 list_a 有来自 list_b 的 1 个条目的所有组合,来生成所需的答案,但是这种方法一旦 len(list_b) > 2 下降。

编辑:这是一个源/汇问题。list_b 是所有需要完全使用的接收器,list_a 是可以为接收器提供输入的源。即对于上述问题,所有 3 个接收器都可以由单个源提供服务(示例 1、5、9、13),或者可以拆分 1 个源 -> 2 个接收器,或者以多种方式 1:1 - 我'我试图找到所有这些方法

标签: pythonpython-3.xpermutationitertools

解决方案


如果不确定我是否理解你的算法。但至少它适用于您的实例。

假设 list_b = [0,1,2 ...] 以便于理解。您的示例可以视为:

['a', 'a']   # [x->'a', y->'a']
['a', 'b']   # [x->'a', y->'b']
['a', 'c']   # [x->'a', y->'c']
...
['d', 'c']   # [x->'d', y->'c']

所以你可以使用

len_b = len(list_b)
itertools.permutations(list_a, len_b)

在这种情况下,将有 12 个项目,并且['a','a'], ['b','b'],...不会由排列生成,因为它是“with_replacement”,这可能是有问题的。

在 python(以及数学)中,排列是位置敏感的,并且不允许重复项。尽管组合允许替换,但它对位置不敏感。

那么为什么您的要求很特别,因为它是置换置换。非常有趣,但恐怕我现在无法解决。

变大了就很难处理list_b了。例如,如果list_b=[i,j,k,l],我们应该考虑

[a,a,b,c]  #[i->a, j->a, k->b, l->c]
[a,b,a,c]  #[i->a, j->b, k->a, l->c]
[a,b,c,a]  #[i->a, j->b, k->c, l->a]

它既不是排列也不是组合。


推荐阅读