Python 获取N个成员的K组和M个成员的L组的组合列表
Python中的;对于给定可能成员列表的Python 获取N个成员的K组和M个成员的L组的组合列表,python,algorithm,python-2.7,combinations,Python,Algorithm,Python 2.7,Combinations,Python中的;对于给定可能成员列表的k组n成员和l组m成员,获得组合列表的最佳方法是什么? 例如,给定一个元素列表: g = ["A", "B", "C", "D", "E", "F", "G"] 我想要的是有一个所有组合的列表,例如2(k)组2(n)和1(l)组3(m): 我不希望元素在任何组中重复出现(相当于说:我希望每个不同的元素在每个不同组合的所有组中出现一次) 例如,[“AB”、“AD”、“EFG”]不是有效的组合,因为它在所有组中多次使用元素a 我不希望在一个组中有不同的排列
k
组n
成员和l
组m
成员,获得组合列表的最佳方法是什么?
例如,给定一个元素列表:
g = ["A", "B", "C", "D", "E", "F", "G"]
我想要的是有一个所有组合的列表,例如2(k
)组2(n
)和1(l
)组3(m
):
[“AB”、“AD”、“EFG”]
不是有效的组合,因为它在所有组中多次使用元素a
[“AB”、“CD”、“EFG”]
不应以类似于[“BA”、“DC”、“EGF”]
的形式重复
k组中
,如果l组
完全相同(并且对于l组
),我不希望在k组中出现相同的组合。
例如,如果出现[“AB”、“CD”、“EFG”]
,[“CD”、“AB”、“EFG”]
g
):
例如2x2+1x3==7==len([“A”、“B”、“C”、“D”、“E”、“F”、“g”)
,1x2+1x3==5==len([“A”、“B”、“C”、“D”、“E”)
我可以在每个排列中使用
k
组n
和l
组m
,但我会有很多不必要的迭代来获得更多的元素。这个问题并不像最初出现的那样简单:每个组都必须是词汇的组合,你们需要所有相互排斥的群的排列
我认为这将需要您编写一个递归生成器,使用字母表和大小列表。类似下面的代码(我恐怕还没有测试过…):
编辑:编辑代码以满足更新的要求(规则3) 代码: 输出:
105
[('AB', 'CD', 'EFG'),
('AB', 'CE', 'DFG'),
...,
('BC', 'AD', 'EFG'),
('BC', 'AE', 'DFG'),
...,
]
有关详细信息和见解,请参阅 编辑:在澄清之后,我添加了一行内容来完成解决方案。。。
这个怎么样,它使用了几个和。无论如何,我认为itertools.combines是您想要使用的:
from itertools import combinations, chain, product
def flatten(listOfLists):
"Flatten one level of nesting"
return chain.from_iterable(listOfLists)
lico = lambda li,x: list( combinations(li,x) )
def get_funky_groups( elements, k,n,l,m ):
kn = lico( lico(elements,n),k) # k groups of n elements
lm = lico( lico( elements,m), l) # l groups of m elements
results = [map( lambda x: "".join(x), flatten(r)) for r in product(kn, lm)]
# added this line so that only each element was used once..
return [ r for r in results if len(set( flatten( r))) == len(g) ]
对于示例列表,这将产生105结果
In [3]: g = ["A", "B", "C", "D", "E", "F", "G"]
In [4]: results = get_funky_groups(g, 2,2,1,3)
In [5]: results[:10]
Out[5]:
[['AB', 'CD', 'EFG'],
['AB', 'CE', 'DFG'],
['AB', 'CF', 'DEG'],
['AB', 'CG', 'DEF'],
['AB', 'DE', 'CFG'],
['AB', 'DF', 'CEG'],
['AB', 'DG', 'CEF'],
['AB', 'EF', 'CDG'],
['AB', 'EG', 'CDF'],
['AB', 'FG', 'CDE']]
In [6]: len( results)
Out[6]: 105
In [7]: g = ["A", "B", "C", "D", "E"]
In [8]: results = get_funky_groups(g, 1,2,1,3)
In [9]: results
Out[9]:
[['AB', 'CDE'],
['AC', 'BDE'],
['AD', 'BCE'],
['AE', 'BCD'],
['BC', 'ADE'],
['BD', 'ACE'],
['BE', 'ACD'],
['CD', 'ABE'],
['CE', 'ABD'],
['DE', 'ABC']]
也许你不想要一个依赖于字符串元素的答案
def get_funky_groups_anyhashable( elements, k,n,l,m ):
kn = lico( lico(elements,n),k) # k groups of n elements
lm = lico( lico( elements,m), l) # l groups of m elements
results = [ list(flatten(r)) for r in product(kn, lm)]
# added this line so that only each element was used once..
return [ r for r in results if len(set( flatten( r))) == len(g) ]
In [103]: g = ["A1", "B2", 232, "D0", 32]
In [104]: get_funky_groups_anyhashable(g, 1,2,1,3)
Out[104]:
[[('A1', 'B2'), (232, 'D0', 32)],
[('A1', 232), ('B2', 'D0', 32)],
[('A1', 'D0'), ('B2', 232, 32)],
[('A1', 32), ('B2', 232, 'D0')],
[('B2', 232), ('A1', 'D0', 32)],
[('B2', 'D0'), ('A1', 232, 32)],
[('B2', 32), ('A1', 232, 'D0')],
[(232, 'D0'), ('A1', 'B2', 32)],
[(232, 32), ('A1', 'B2', 'D0')],
[('D0', 32), ('A1', 'B2', 232)]]
同样值得注意的是,如果性能成为问题
In [132]: lico( combinations( g,2),1) == lico( lico( g,2),1 )
Out[132]: True
可以在一个字符串中复制元素吗?例如,拥有
[“AB”、“BC”、“EFE”]
是否合法。无法在其他子组中重复任何元素。是否修复您的发布?你已经在一些例子中重复了B和C,比如[“AB”,“BC”,“EFG”]
根据你的解释,我给出的答案是错误的:它在不同的组中重复出现。这个问题并不像最初出现的那样简单:每个组都必须是词典中的一个组合,并且您需要组的所有互斥排列。您想要[“AB”,“CD”,“EFG”]
和[“CD”,“AB”,“EFG”]
或其中一个?返回一个空的生成器。如果不清楚,很抱歉,但这不是我要找的。例如,您的第一次迭代['AB'、'AC'、'ABC']
:每个元素只能有一次,因此您不能在任何组中有多个A
',多个B
,多个C
。(我编辑了原始帖子;请参见规则#1)。嗯,我想你可以检查展平元素集,如我添加的简单编辑所示。通过使用组合
工具,与链接到的置换
itertool相比,您已经完成了少得多的迭代。。但是你可以进一步优化…我想你就快到了。用g1=unique_组(iterable,1,2)
和g2=unique_组(iterable,1,3)
尝试这种方法会导致[('AD','BCE'),('AE','BCD'),('BC','ADE'),('BD','ACE'),('BE','ACD'),('CD','ABE'),('CE','ABD'),('DE','ABC')]
。例如,缺少组合('AB','CDE')
和('AC','BDE')
。通过您的新输入,我将获得所有这些组合(10项列表)。
In [3]: g = ["A", "B", "C", "D", "E", "F", "G"]
In [4]: results = get_funky_groups(g, 2,2,1,3)
In [5]: results[:10]
Out[5]:
[['AB', 'CD', 'EFG'],
['AB', 'CE', 'DFG'],
['AB', 'CF', 'DEG'],
['AB', 'CG', 'DEF'],
['AB', 'DE', 'CFG'],
['AB', 'DF', 'CEG'],
['AB', 'DG', 'CEF'],
['AB', 'EF', 'CDG'],
['AB', 'EG', 'CDF'],
['AB', 'FG', 'CDE']]
In [6]: len( results)
Out[6]: 105
In [7]: g = ["A", "B", "C", "D", "E"]
In [8]: results = get_funky_groups(g, 1,2,1,3)
In [9]: results
Out[9]:
[['AB', 'CDE'],
['AC', 'BDE'],
['AD', 'BCE'],
['AE', 'BCD'],
['BC', 'ADE'],
['BD', 'ACE'],
['BE', 'ACD'],
['CD', 'ABE'],
['CE', 'ABD'],
['DE', 'ABC']]
def get_funky_groups_anyhashable( elements, k,n,l,m ):
kn = lico( lico(elements,n),k) # k groups of n elements
lm = lico( lico( elements,m), l) # l groups of m elements
results = [ list(flatten(r)) for r in product(kn, lm)]
# added this line so that only each element was used once..
return [ r for r in results if len(set( flatten( r))) == len(g) ]
In [103]: g = ["A1", "B2", 232, "D0", 32]
In [104]: get_funky_groups_anyhashable(g, 1,2,1,3)
Out[104]:
[[('A1', 'B2'), (232, 'D0', 32)],
[('A1', 232), ('B2', 'D0', 32)],
[('A1', 'D0'), ('B2', 232, 32)],
[('A1', 32), ('B2', 232, 'D0')],
[('B2', 232), ('A1', 'D0', 32)],
[('B2', 'D0'), ('A1', 232, 32)],
[('B2', 32), ('A1', 232, 'D0')],
[(232, 'D0'), ('A1', 'B2', 32)],
[(232, 32), ('A1', 'B2', 'D0')],
[('D0', 32), ('A1', 'B2', 232)]]
In [132]: lico( combinations( g,2),1) == lico( lico( g,2),1 )
Out[132]: True