首页 文章

Python组合和产品

提问于
浏览
3

我有一个dataframes列列表:

L=[AA ,  AS  ,  AD  , BB  , BC  , CD ,  CF,CG ]

我需要所有项目的组合,没有特别的顺序 .

但是,我在每个组合中只能有一个以A开头的名称但是我可以有多个以C开头或没有的名称 .

关于B,我必须至少有一个B但可能有更多

所以我需要所有的组合

A=[AA,AS,AD] #only one of these
B=[BB,BC]  #at least one of these
all_others=[CD,CF,CG]  #All, 1, 2 or none of these

到目前为止我有这个代码;

from itertools import product

for choices in product(['AA','AS','AD',None],['BB', 'BC', None], ['CD','CF', None],):
    print(' '.join(column for column in choices if column))

这是有效的,但是,它只允许一个以C开头的值,但我想 product 所有C.的组合 . 任何人都可以看到我可以做出的良好编辑吗?

总结一下;我需要列表中所有名称的组合 . 使用一条规则,您不能有超过1个以A开头的变量和多个以B开头的变量

3 回答

  • 1

    这是一种更健壮/更通用的方式来做你想要的事情 . 我首先定义一个辅助函数:

    from itertools import combinations, chain, product
    
    def subsets_of_length(s, lengths):
        return chain.from_iterable(combinations(s,l) for l in lengths)
    

    它产生以下输出:

    >>>> list(subsets_of_length(['a','b','c'], range(2,4)))
    [('a', 'b'), ('a', 'c'), ('b', 'c'), ('a', 'b', 'c')]
    
    >>>> list(subsets_of_length(['d','e'], range(0,2)))
    [(), ('d',), ('e',)]
    

    现在我们想要组合两个或更多子集,如下所示

    >>>> for choices in product(
             subsets_of_length(['a','b','c'], range(2,4)),
             subsets_of_length(['d','e'], range(0,2)),
         ):
             print(' '.join(str(subset) for subset in choices))
    
    ('a', 'b') ()
    ('a', 'b') ('d',)
    ('a', 'b') ('e',)
    ('a', 'c') ()
    ('a', 'c') ('d',)
    ('a', 'c') ('e',)
    ('b', 'c') ()
    ('b', 'c') ('d',)
    ('b', 'c') ('e',)
    ('a', 'b', 'c') ()
    ('a', 'b', 'c') ('d',)
    ('a', 'b', 'c') ('e',)
    

    但我们希望将这些元组链接在一起 . 因此我们应该这样做

    >>>> for choices in map(chain.from_iterable,product(
             subsets_of_length(['a','b','c'], range(2,4)),
             subsets_of_length(['d','e'], range(0,2)),
         )):
             print(' '.join(column for column in choices if column))
    
    a b
    a b d
    a b e
    a c
    a c d
    a c e
    b c
    b c d
    b c e
    a b c
    a b c d
    a b c e
    

    您编辑的问题的代码将是:

    for choices in map(chain.from_iterable,product(
        subsets_of_length(['AA','AS','AD'], [1]),       #only one of these
        subsets_of_length(['BB','BC'], [1,2]),          #at least one of these
        subsets_of_length(['CD','CF','CG'], [0,1,2,3]), #All, 1, 2 or none of these
    )):
        print(' '.join(column for column in choices if column))
    
  • 1

    试试这个而不是 for 循环:

    for choices in itertools.product(['AA','AS','AD',None],['BB', 'BC', None],[' '.join(k) for j in list(itertools.combinations(['CD','CF'],i) for i in range(3)) for k in j]):
        # do what you need
    

    使用 print(' '.join(column for column in choices if column)) 的选项输出是:

    AA BB
    AA BB CD
    AA BB CF
    AA BB CD CF
    AA BC
    AA BC CD
    AA BC CF
    AA BC CD CF
    AA
    AA CD
    AA CF
    AA CD CF
    AS BB
    AS BB CD
    AS BB CF
    AS BB CD CF
    AS BC
    AS BC CD
    AS BC CF
    AS BC CD CF
    AS
    AS CD
    AS CF
    AS CD CF
    AD BB
    AD BB CD
    AD BB CF
    AD BB CD CF
    AD BC
    AD BC CD
    AD BC CF
    AD BC CD CF
    AD
    AD CD
    AD CF
    AD CD CF
    BB
    BB CD
    BB CF
    BB CD CF
    BC
    BC CD
    BC CF
    BC CD CF
    
    CD
    CF
    CD CF
    

    我建议你用 '' 替换 None 或删除它们 .

  • 2

    当然,要表达

    all_others=[CD,CF,CG]  #All, 1, 2 or none of these
    

    打破它

    all_others=[CD]  #one or none of these
    all_others=[CF]  #one or none of these
    all_others=[CG]  #one or none of these
    

    然后你的代码变成了

    from itertools import product
    
    for choices in product(['AA','AS','AD',None],['BB', 'BC', None], ['CD', None], ['CF', None], ['CG', None],):
        print(' '.join(column for column in choices if column))
    

    这处理这个特定的例子 . 但是,如果你有几个以C开头的项目,可以按如下方式更系统地处理它们:

    from itertools import product
    
    for choices in product(['AA','AS','AD',None],['BB', 'BC', None], *product(['CD', 'CF', 'CG'], [None]),):
        print(' '.join(column for column in choices if column))
    

    为了解释发生了什么,将 ['CD', 'CF', 'CG'][None] 的乘积产生一个包含的迭代器

    ('CD', None), ('CF', None), ('CG', None)
    

    这些正是我们希望传递给 product 的参数 * 运算符将迭代器内的元素转换为函数参数 . 因此,上述两个代码片段是等效的 .

相关问题