【问题标题】:How to get all combinations of elements ignoring a suffix?如何获得忽略后缀的所有元素组合?
【发布时间】:2017-11-20 10:01:25
【问题描述】:

假设我有四个这样的元素

test = ['A', 'B', 'C', 'D']

然后我可以很容易地得到由三个元素组成的所有组合像这样

import itertools as it
list(it.combinations(test, 3))

给了

 [('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D')]

不过,现在我还有几个后缀,例如

suff = ['x', 'y']

我想考虑一下。我的想要的结果是这样的

[('A__x', 'B__x', 'C__x'),
 ('A__x', 'B__x', 'C__y'),
 ('A__x', 'B__x', 'D__x'),
 ('A__x', 'B__x', 'D__y'),
 ('A__x', 'B__y', 'C__x'),
 ('A__x', 'B__y', 'C__y'),
 ('A__x', 'B__y', 'D__x'),
 ('A__x', 'B__y', 'D__y'),
 ('A__x', 'C__x', 'D__x'),
 ('A__x', 'C__x', 'D__y'),
 ('A__x', 'C__y', 'D__x'),
 ('A__x', 'C__y', 'D__y'),
 ('A__y', 'B__x', 'C__x'),
 ('A__y', 'B__x', 'C__y'),
 ('A__y', 'B__x', 'D__x'),
 ('A__y', 'B__x', 'D__y'),
 ('A__y', 'B__y', 'C__x'),
 ('A__y', 'B__y', 'C__y'),
 ('A__y', 'B__y', 'D__x'),
 ('A__y', 'B__y', 'D__y'),
 ('A__y', 'C__x', 'D__x'),
 ('A__y', 'C__x', 'D__y'),
 ('A__y', 'C__y', 'D__x'),
 ('A__y', 'C__y', 'D__y'),
 ('B__x', 'C__x', 'D__x'),
 ('B__x', 'C__x', 'D__y'),
 ('B__x', 'C__y', 'D__x'),
 ('B__x', 'C__y', 'D__y'),
 ('B__y', 'C__x', 'D__x'),
 ('B__y', 'C__x', 'D__y'),
 ('B__y', 'C__y', 'D__x'),
 ('B__y', 'C__y', 'D__y')]

所以我想找到两个后缀的所有三个组合,但在这个后缀前面的所有内容中都没有重复(例如,我不想要 ('A__x', 'A__y', 'C__x'),因为会有两个 A)。

我目前实现如下:

import itertools as it

def filter_elements(some_elements, connector):

    # get all elements in front of the connector
    all_elements = [eli.split(connector)[0] for eli in some_elements]

    # return True if all elements are unique
    return len(all_elements) == len(set(all_elements))

test = ['A', 'B', 'C', 'D']

suff = ['x', 'y']

connector = '__'

test_suff = ["{}{}{}".format(eli, connector, si) for eli in test for si in suff]

all_combinations = list(it.combinations(test_suff, 3))

desired_combinations = [combi for combi in all_combinations if filter_elements(combi, connector)]

这给了我想要的输出。

显然,这不仅适用于四个元素和两个后缀,还适用于任意组合。有没有更直接的方法可以避免创建all_combinations

【问题讨论】:

    标签: python performance combinations itertools


    【解决方案1】:

    我认为你只需要it.product:

    >>> list(it.product('xy', repeat=3))
    [('x', 'x', 'x'),
     ('x', 'x', 'y'),
     ('x', 'y', 'x'),
     ('x', 'y', 'y'),
     ('y', 'x', 'x'),
     ('y', 'x', 'y'),
     ('y', 'y', 'x'),
     ('y', 'y', 'y')]
    

    所以如果你想要上面列出的 32 个元组:

    list(it.product(it.combinations(test, 3), it.product(suff,repeat=3)))
    

    返回:

    [(('A', 'B', 'C'), ('x', 'x', 'x')),
     (('A', 'B', 'C'), ('x', 'x', 'y')),
     (('A', 'B', 'C'), ('x', 'y', 'x')),
     (('A', 'B', 'C'), ('x', 'y', 'y')),
     (('A', 'B', 'C'), ('y', 'x', 'x')),
     (('A', 'B', 'C'), ('y', 'x', 'y')),
     (('A', 'B', 'C'), ('y', 'y', 'x')),
     (('A', 'B', 'C'), ('y', 'y', 'y')),
     (('A', 'B', 'D'), ('x', 'x', 'x')),
     (('A', 'B', 'D'), ('x', 'x', 'y')),
     (('A', 'B', 'D'), ('x', 'y', 'x')),
     (('A', 'B', 'D'), ('x', 'y', 'y')),
     (('A', 'B', 'D'), ('y', 'x', 'x')),
     (('A', 'B', 'D'), ('y', 'x', 'y')),
     (('A', 'B', 'D'), ('y', 'y', 'x')),
     (('A', 'B', 'D'), ('y', 'y', 'y')),
     (('A', 'C', 'D'), ('x', 'x', 'x')),
     (('A', 'C', 'D'), ('x', 'x', 'y')),
     (('A', 'C', 'D'), ('x', 'y', 'x')),
     (('A', 'C', 'D'), ('x', 'y', 'y')),
     (('A', 'C', 'D'), ('y', 'x', 'x')),
     (('A', 'C', 'D'), ('y', 'x', 'y')),
     (('A', 'C', 'D'), ('y', 'y', 'x')),
     (('A', 'C', 'D'), ('y', 'y', 'y')),
     (('B', 'C', 'D'), ('x', 'x', 'x')),
     (('B', 'C', 'D'), ('x', 'x', 'y')),
     (('B', 'C', 'D'), ('x', 'y', 'x')),
     (('B', 'C', 'D'), ('x', 'y', 'y')),
     (('B', 'C', 'D'), ('y', 'x', 'x')),
     (('B', 'C', 'D'), ('y', 'x', 'y')),
     (('B', 'C', 'D'), ('y', 'y', 'x')),
     (('B', 'C', 'D'), ('y', 'y', 'y'))]
    

    为了得到想要的格式,需要使用zipjoin

    [tuple('__'.join(ls) for ls in zip(*t)) for t in it.product(it.combinations(test, 3), it.product(suff,repeat=3))]
    

    返回:

    [('A__x', 'B__x', 'C__x'),
     ('A__x', 'B__x', 'C__y'),
     ('A__x', 'B__y', 'C__x'),
     ('A__x', 'B__y', 'C__y'),
     ('A__y', 'B__x', 'C__x'),
     ('A__y', 'B__x', 'C__y'),
     ('A__y', 'B__y', 'C__x'),
     ('A__y', 'B__y', 'C__y'),
     ('A__x', 'B__x', 'D__x'),
     ('A__x', 'B__x', 'D__y'),
     ('A__x', 'B__y', 'D__x'),
     ('A__x', 'B__y', 'D__y'),
     ('A__y', 'B__x', 'D__x'),
     ('A__y', 'B__x', 'D__y'),
     ('A__y', 'B__y', 'D__x'),
     ('A__y', 'B__y', 'D__y'),
     ('A__x', 'C__x', 'D__x'),
     ('A__x', 'C__x', 'D__y'),
     ('A__x', 'C__y', 'D__x'),
     ('A__x', 'C__y', 'D__y'),
     ('A__y', 'C__x', 'D__x'),
     ('A__y', 'C__x', 'D__y'),
     ('A__y', 'C__y', 'D__x'),
     ('A__y', 'C__y', 'D__y'),
     ('B__x', 'C__x', 'D__x'),
     ('B__x', 'C__x', 'D__y'),
     ('B__x', 'C__y', 'D__x'),
     ('B__x', 'C__y', 'D__y'),
     ('B__y', 'C__x', 'D__x'),
     ('B__y', 'C__x', 'D__y'),
     ('B__y', 'C__y', 'D__x'),
     ('B__y', 'C__y', 'D__y')]
    

    【讨论】:

      猜你喜欢
      • 2010-10-02
      • 2018-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多