X 列表的条件笛卡尔积,导致带有 k,v 对的字典?

Conditional Cartesian product of a X lists, resulting in dict with k,v pairs?

我有如下列表:

LISTA = ['A1', 'A2']
LISTB = ['B1', 'B2']
LISTC = ['C1']
LISTD = ['D1', 'D2']
LISTE = ['E1', 'E2', 'E3']

我想编写一个函数来获取 LISTXLISTY 的笛卡尔积,然后根据每个元组中 LISTY 的值,我会喜欢添加 LISTJ 的产品或 LISTK 的产品。所有命名为 key/value 对,或作为列表,其中 [0] 是键,[1] 是值。

即如果 X == LISTAY == LISTBJ == LISTCK == LISTE,我们假设如果有值 B1,我们得到 J(LISTC)B2 我们用 K(LISTE) 得到产品,然后我们应该得到像...

[{'LISTA': A1, 'LISTB': B1 'LISTC': C1},
 {'LISTA': A1, 'LISTB': B2 'LISTE': E1},
 {'LISTA': A1, 'LISTB': B2 'LISTE': E2},
 {'LISTA': A1, 'LISTB': B2 'LISTE': E3},
 {'LISTA': A2, 'LISTB': B1 'LISTC': C1},
 {'LISTA': A2, 'LISTB': B2 'LISTE': E1},
 {'LISTA': A2, 'LISTB': B2 'LISTE': E2},
 {'LISTA': A2, 'LISTB': B2 'LISTE': E3}]

我认为这可能是沿着这些思路,我们首先获得产品,然后使用生成器以便 return 该产品中每个元组的字典,以及分配的 k,v 对来自 jk。但是,我无法弄清楚如何使它比在参数中包含 'y_val' 更通用,而且我也不确定如何在 J_OR_K 中分配键,而不仅仅是结束像 (('LISTA', A1), ('LISTB', B1), C1).

这样的元组
import itertools as it

def J_OR_K(P, y_val1, y_val2, j_list, k_list):
    for k, v in P:
        for x in {y_val1:j_list, y_val2:k_list}[v]:
            yield {a,b,x}

def my_func(x, y, j, k):
    res = []
    # get cartesian product of x, y
    prod_xy = it.product(it.product(['LISTA'], x), 
                         it.product(['LISTB'], y))
    # get product with EITHER J OR K
    for t in J_OR_K(j, k):
        res.append(t)

尽管这与我之前 的一个问题类似,但它略有不同且涉及更多 - 所以我觉得它需要一个新问题。

以下嵌套推导式可以达到您的示例的预期效果:

>>> from itertools import product as p
>>> [x + y for x in p(LISTA, LISTB) for y in p(LISTC if x[1] == 'B1' else LISTE)]
[('A1', 'B1', 'C1'),
 ('A1', 'B2', 'E1'),
 ('A1', 'B2', 'E2'),
 ('A1', 'B2', 'E3'),
 ('A2', 'B1', 'C1'),
 ('A2', 'B2', 'E1'),
 ('A2', 'B2', 'E2'),
 ('A2', 'B2', 'E3')]

这是解决方案的交互式演示:

>>> import itertools
>>> LISTA = ['A1', 'A2']
>>> LISTB = ['B1', 'B2']
>>> LISTC = ['C1']
>>> LISTD = ['D1', 'D2']
>>> LISTE = ['E1', 'E2', 'E3']
>>> def f():
...    for a,b in itertools.product(LISTA,LISTB):
...       n, l = {"B1":["LISTC",LISTC], "B2":["LISTE",LISTE]}[b]
...       for x in l:
...          yield {"LISTA":a, "LISTB":b, n:x}
... 
>>> from pprint import pprint
>>> pprint(list(f()))
[{'LISTA': 'A1', 'LISTB': 'B1', 'LISTC': 'C1'},
 {'LISTA': 'A1', 'LISTB': 'B2', 'LISTE': 'E1'},
 {'LISTA': 'A1', 'LISTB': 'B2', 'LISTE': 'E2'},
 {'LISTA': 'A1', 'LISTB': 'B2', 'LISTE': 'E3'},
 {'LISTA': 'A2', 'LISTB': 'B1', 'LISTC': 'C1'},
 {'LISTA': 'A2', 'LISTB': 'B2', 'LISTE': 'E1'},
 {'LISTA': 'A2', 'LISTB': 'B2', 'LISTE': 'E2'},
 {'LISTA': 'A2', 'LISTB': 'B2', 'LISTE': 'E3'}]
>>>