Python 获取N个成员的K组和M个成员的L组的组合列表

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 我不希望在一个组中有不同的排列

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

  • 我不希望在一个组中有不同的排列方式

    例如,
    [“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