不同大小的笛卡尔积

问题描述 投票:2回答:2

由于具有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
python list itertools cartesian-product
2个回答
4
投票
>>> 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
投票

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

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')
© www.soinside.com 2019 - 2024. All rights reserved.