如何生成具有相关笛卡尔积的笛卡尔积

时间:2021-02-02 11:22:24

标签: python itertools cartesian-product

如何使用 itertools 或类似工具获得以下所需结果? itertools.product 与 Boolean x Boolean x Range x Range 会产生许多不希望的结果。

A1, A2 应该仅在 use_A is True

的情况下迭代

B1, B2 应该仅在 use_B is True

的情况下迭代

它必须是最有效的方式,因为完整的 product_config 有超过 50 亿种不同的组合。

product_config = {
    'use_A': [False, True],
    'A1': range(3),
    'A2': range(3),
    'use_B': [False, True],
    'B1': range(3),
    'B2': range(3)
}

# Desired results:
res = [
    {'use_A': False, 'use_B': False},
    {'use_A': True, 'A1': 0, 'A2': 0, 'use_B': False},
    {'use_A': True, 'A1': 0, 'A2': 1, 'use_B': False},
    {'use_A': True, 'A1': 0, 'A2': 2, 'use_B': False},
    {'use_A': True, 'A1': 1, 'A2': 0, 'use_B': False},
    {'use_A': True, 'A1': 1, 'A2': 1, 'use_B': False},
    {'use_A': True, 'A1': 1, 'A2': 2, 'use_B': False},
    {'use_A': True, 'A1': 2, 'A2': 0, 'use_B': False},
    {'use_A': True, 'A1': 2, 'A2': 1, 'use_B': False},
    {'use_A': True, 'A1': 2, 'A2': 2, 'use_B': False},
    {'use_A': True, 'A1': 0, 'A2': 0, 'use_B': True, 'B1': 0, 'B2': 0},
    {'use_A': True, 'A1': 0, 'A2': 1, 'use_B': True, 'B1': 0, 'B2': 1},
    {'use_A': True, 'A1': 0, 'A2': 2, 'use_B': True, 'B1': 0, 'B2': 2},
    {'use_A': True, 'A1': 1, 'A2': 0, 'use_B': True, 'B1': 1, 'B2': 0},
    {'use_A': True, 'A1': 1, 'A2': 1, 'use_B': True, 'B1': 1, 'B2': 1},
    {'use_A': True, 'A1': 1, 'A2': 2, 'use_B': True, 'B1': 1, 'B2': 2},
    {'use_A': True, 'A1': 2, 'A2': 0, 'use_B': True, 'B1': 2, 'B2': 0},
    {'use_A': True, 'A1': 2, 'A2': 1, 'use_B': True, 'B1': 2, 'B2': 1},
    {'use_A': True, 'A1': 2, 'A2': 2, 'use_B': True, 'B1': 2, 'B2': 2},
    {'use_A': False, 'use_B': True, 'B1': 0, 'B2': 0},
    {'use_A': False, 'use_B': True, 'B1': 0, 'B2': 1},
    {'use_A': False, 'use_B': True, 'B1': 0, 'B2': 2},
    {'use_A': False, 'use_B': True, 'B1': 1, 'B2': 0},
    {'use_A': False, 'use_B': True, 'B1': 1, 'B2': 1},
    {'use_A': False, 'use_B': True, 'B1': 1, 'B2': 2},
    {'use_A': False, 'use_B': True, 'B1': 2, 'B2': 0},
    {'use_A': False, 'use_B': True, 'B1': 2, 'B2': 1},
    {'use_A': False, 'use_B': True, 'B1': 2, 'B2': 2},
]

1 个答案:

答案 0 :(得分:0)

通过 itertools,我们可以使用以下内容:

import itertools
import pprint

pp = pprint.PrettyPrinter(indent=4)
b1 = [False, True]
t1 = itertools.product(b1, b1)
res = []
for t in t1:
    i1 = itertools.product(range(3), range(3))
    for i in i1:
        rdict = {'use_A': t[0], 'use_B': t[1]}
        if not t[0] and not t[1]:
            res.append(rdict)
            break
        if t[0]:
            rdict['A1'] = i[0]
            rdict['A2'] = i[1]
        if t[1]:
            rdict['B1'] = i[0]
            rdict['B2'] = i[1]
        res.append(rdict)
pp.pprint(res)

输出

[   {'use_A': False, 'use_B': False},
    {'B1': 0, 'B2': 0, 'use_A': False, 'use_B': True},
    {'B1': 0, 'B2': 1, 'use_A': False, 'use_B': True},
    {'B1': 0, 'B2': 2, 'use_A': False, 'use_B': True},
    {'B1': 1, 'B2': 0, 'use_A': False, 'use_B': True},
    {'B1': 1, 'B2': 1, 'use_A': False, 'use_B': True},
    {'B1': 1, 'B2': 2, 'use_A': False, 'use_B': True},
    {'B1': 2, 'B2': 0, 'use_A': False, 'use_B': True},
    {'B1': 2, 'B2': 1, 'use_A': False, 'use_B': True},
    {'B1': 2, 'B2': 2, 'use_A': False, 'use_B': True},
    {'A1': 0, 'A2': 0, 'use_A': True, 'use_B': False},
    {'A1': 0, 'A2': 1, 'use_A': True, 'use_B': False},
    {'A1': 0, 'A2': 2, 'use_A': True, 'use_B': False},
    {'A1': 1, 'A2': 0, 'use_A': True, 'use_B': False},
    {'A1': 1, 'A2': 1, 'use_A': True, 'use_B': False},
    {'A1': 1, 'A2': 2, 'use_A': True, 'use_B': False},
    {'A1': 2, 'A2': 0, 'use_A': True, 'use_B': False},
    {'A1': 2, 'A2': 1, 'use_A': True, 'use_B': False},
    {'A1': 2, 'A2': 2, 'use_A': True, 'use_B': False},
    {'A1': 0, 'A2': 0, 'B1': 0, 'B2': 0, 'use_A': True, 'use_B': True},
    {'A1': 0, 'A2': 1, 'B1': 0, 'B2': 1, 'use_A': True, 'use_B': True},
    {'A1': 0, 'A2': 2, 'B1': 0, 'B2': 2, 'use_A': True, 'use_B': True},
    {'A1': 1, 'A2': 0, 'B1': 1, 'B2': 0, 'use_A': True, 'use_B': True},
    {'A1': 1, 'A2': 1, 'B1': 1, 'B2': 1, 'use_A': True, 'use_B': True},
    {'A1': 1, 'A2': 2, 'B1': 1, 'B2': 2, 'use_A': True, 'use_B': True},
    {'A1': 2, 'A2': 0, 'B1': 2, 'B2': 0, 'use_A': True, 'use_B': True},
    {'A1': 2, 'A2': 1, 'B1': 2, 'B2': 1, 'use_A': True, 'use_B': True},
    {'A1': 2, 'A2': 2, 'B1': 2, 'B2': 2, 'use_A': True, 'use_B': True}]