任意格数的笛卡尔积的和元组

时间:2018-11-17 09:12:45

标签: python dictionary

我想根据多个字典的键对它们进行笛卡尔乘积运算,然后对生成的元组求和,并将其作为字典返回。应该忽略一个字典中不存在的键(此约束是理想的,但不是必需的;即,如果需要,您可以假设所有字典中都存在所有键)。下面基本上是我想要达到的目的(带有两个字典的示例)。是否有更简单的方法以及N格?

def doProdSum(inp1, inp2):
    prod = defaultdict(lambda: 0)
    for key in set(list(inp1.keys())+list(inp2.keys())):
        if key not in prod:
            prod[key] = []
        if key not in inp1 or key not in inp2:
            prod[key] = inp1[key] if key in inp1 else inp2[key]
            continue
        for values in itertools.product(inp1[key], inp2[key]):
            prod[key].append(values[0] + values[1])
    return prod

x = doProdSum({"a":[0,1,2],"b":[10],"c":[1,2,3,4]}, {"a":[1,1,1],"b":[1,2,3,4,5]})
print(x)

输出(按预期):

  

{'c':[1,2,3,4],'b':[11,12,13,14,15],'a':[1,1,1,2,2,2 ,   3,3,3]}

1 个答案:

答案 0 :(得分:1)

您可以这样操作,首先通过密钥重新组织数据:

from collections import defaultdict
from itertools import product


def doProdSum(list_of_dicts):
    # We reorganize the data by key
    lists_by_key = defaultdict(list)
    for d in list_of_dicts:
        for k, v in d.items():
            lists_by_key[k].append(v)

    # list_by_key looks like {'a': [[0, 1, 2], [1, 1, 1]], 'b': [[10], [1, 2, 3, 4, 5]],'c': [[1, 2, 3, 4]]}

    # Then we generate the output
    out = {}
    for key, lists in lists_by_key.items():
        out[key] = [sum(prod) for prod in product(*lists)]

    return out

示例输出:

list_of_dicts = [{"a":[0,1,2],"b":[10],"c":[1,2,3,4]}, {"a":[1,1,1],"b":[1,2,3,4,5]}]
doProdSum(list_of_dicts)

# {'a': [1, 1, 1, 2, 2, 2, 3, 3, 3],
#  'b': [11, 12, 13, 14, 15],
#  'c': [1, 2, 3, 4]}