合并长度为a、b、c等的Python列表生成长度为a*b*c*的列表

0 投票
2 回答
68 浏览
提问于 2025-04-14 16:06

我有两个Python对象,如下所示:

data1 = [{"key1": i} for i in range(331)]
data2 = [{"key2": i} for i in range(4)]

我创建了一个合并后的对象,像这样:

merged_data = []
for item_a in data1:
    for item_b in data2:
        merged_data.append({**item_a, **item_b})

但是,如果有一个叫做 data 的变量,里面包含了 n 个对象,如下所示:

data1 = [{"key1": i} for i in range(331)]
data2 = [{"key2": i} for i in range(4)]
.
.
.
.
dataN = [{"keyN" : i} for i in range(n)]

data = [data1, data2, .... dataN]

那么,从这个叫做 data 的变量中,如何得到一个像这样的合并列表呢?

[{'key1': 0, 'key2': 0, ...., "keyN" : 0},
 {'key1': 0, 'key2': 0, ...., "keyN" : 1},
 {'key1': 0, 'key2': 0, ...., "keyN" : 2},
 {'key1': 0, 'key2': 0, ...., "keyN" : 3},
 {'key1': 0, 'key2': 0, ...., "keyN" : 4},
 .
 .
 .
 .
 {'key1': 330, 'key2': 3,...., "keyN" : n}]

2 个回答

-1

感谢大家的回答。我按照这个方法得到了结果。谢谢!

mergedDat = []
for values in itertools.product(*data):
    mergedDict = {}
    for i, value in enumerate(values):
        mergedDict.update(value)
    mergedDat.append(mergedDict)
2

使用Itertools来解决问题:

itertools.product(*iterables, repeat=1)

这是输入可迭代对象的笛卡尔积。

大致上相当于在生成器表达式中使用嵌套的for循环。比如说,product(A, B)的结果和((x,y) for x in A for y in B)是一样的。

给定你的dataitertools.product(*data)会生成一个迭代器,输出像({'key1': 0}, {'key2': 0}, ...., {"keyN" : 0})这样的元组,所以你只需要把它们合并起来。对于一个可迭代对象,我们可以使用functools.reduce来“合并”所有这些项目。我们可以使用operator模块来获取一个函数版本的a |= b,这个操作用于就地合并字典。

我们可以利用reduce的第三个参数,把它们放入一个新的字典中。

把这些结合起来:

from functools import reduce
from itertools import product
from operator import ior

merged_list = [reduce(ior, dictionaries, {}) for dictionaries in product(*data)]

撰写回答