代码之家  ›  专栏  ›  技术社区  ›  Sildar

不同大小的笛卡尔积

  •  1
  • Sildar  · 技术社区  · 10 年前

    多亏了 itertools.product() 功能:

    lists = [['A', 'B'], ['1', '2'], ['x', 'y']]
    combinations = itertools.product(*lists)
    # [('A', '1', 'x'), ('A', '2', 'y'), ..., ('B', '2', 'y')]
    

    我想要的是相同的东西,但尺寸不同:

    all_comb = magicfunction(lists)
    # [('A', '1', 'x'), ..., ('B', '2', 'y'), ('A', '1'), ('A', '2'), ... ('2', 'y'), ... ('y')]
    

    我看不出一个明显的方法。

    我需要一种方法,可以让我设置元组的最小和最大大小(我处理长列表,只需要7到3个大小的组合,列表的数量和大小各不相同)。

    我的列表更像:

    lists = [['A', 'B', 'C'], ['1', '2'], ['x', 'y', 'z', 'u'], ...] # size may go to a few dozens
    
    2 回复  |  直到 5 年前
        1
  •  4
  •   Ashwini Chaudhary    10 年前
    >>> from itertools import product, combinations
    >>> lists = [['A', 'B'], ['1', '2'], ['x', 'y']]
    >>> for i in xrange(2, len(lists)+1):
        for c in combinations(lists, i):
            print list(product(*c))
    ...         
    [('A', '1'), ('A', '2'), ('B', '1'), ('B', '2')]
    [('A', 'x'), ('A', 'y'), ('B', 'x'), ('B', 'y')]
    [('1', 'x'), ('1', 'y'), ('2', 'x'), ('2', 'y')]
    [('A', '1', 'x'), ('A', '1', 'y'), ('A', '2', 'x'), ('A', '2', 'y'), ('B', '1', 'x'), ('B', '1', 'y'), ('B', '2', 'x'), ('B', '2', 'y')]
    
        2
  •  2
  •   Martijn Pieters    10 年前

    根据较小尺寸的组合,只需将几个产品链在一起:

    from itertools import chain, product, combinations
    
    def ranged_product(*lists, **start_stop):
        start, stop = start_stop.get('start', len(lists)), start_stop.get('stop', 0)
        return chain.from_iterable(product(*comb)
                                   for size in xrange(start, stop - 1, -1)
                                   for comb in combinations(lists, r=size))
    

    演示:

    >>> lists = [['A', 'B'], ['1', '2'], ['x', 'y']]
    >>> for prod in ranged_product(stop=2, *lists):
    ...     print prod
    ... 
    ('A', '1', 'x')
    ('A', '1', 'y')
    ('A', '2', 'x')
    ('A', '2', 'y')
    ('B', '1', 'x')
    ('B', '1', 'y')
    ('B', '2', 'x')
    ('B', '2', 'y')
    ('A', '1')
    ('A', '2')
    ('B', '1')
    ('B', '2')
    ('A', 'x')
    ('A', 'y')
    ('B', 'x')
    ('B', 'y')
    ('1', 'x')
    ('1', 'y')
    ('2', 'x')
    ('2', 'y')