[英]Cartesian product of multiple lists of dictionaries
我有两个或更多的字典,每个字典都是字典列表(类似于json格式),例如:
list_1 = [{'Name': 'John' , 'Age': 25} , {'Name': 'Mary' , 'Age': 15}]
list_2 = [{'Product': 'Car', 'Id': 1} , {'Product': 'TV' , 'Id': 2}]
cartesian_product(list_1 * list_2) = [{'Name': 'John', 'Age':25, 'Product': 'Car', 'Id': 1}, {'Name': 'John', 'Age':25, 'Product': 'TV', 'Id': 2}, {'Name': 'Mary' , 'Age': 15, 'Product': 'Car', 'Id': 1}, {'Name': 'Mary' , 'Age': 15, 'Product': 'TV', 'Id': 2}]
我怎样才能做到这一点,并在使用内存时高效? 我现在正在这样做的方式是用大量列表的RAM。 我知道它可能与itertools.product有关,但我无法弄清楚如何用一个dicts列表来做这件事。 谢谢。
PD:我现在这样做:
gen1 = (row for row in self.tables[0])
table = []
for row in gen1:
gen2 = (dictionary for table in self.tables[1:] for dictionary in table)
for element in gen2:
new_row = {}
new_row.update(row)
new_row.update(element)
table.append(new_row)
谢谢!
以下是发布问题的解决方案:
list_1 = [{'Name': 'John' , 'Age': 25} , {'Name': 'Mary' , 'Age': 15}]
list_2 = [{'Product': 'Car', 'Id': 1} , {'Product': 'TV' , 'Id': 2}]
from itertools import product
ret_list = []
for i1, i2 in product(list_1, list_2):
merged = {}
merged.update(i1)
merged.update(i2)
ret_list.append(merged)
这里的关键是利用dicts
的update
功能来添加成员。 此版本将保留父级dicts未修改。 并将默默地删除重复键,以支持最后看到的任何内容。
但是,这对内存使用没有帮助。 简单的事实是,如果要在内存中执行此操作,则需要能够存储起始列表和生成的产品。 替代方案包括定期写入磁盘或将起始数据分成块并随时删除块。
只需将字典转换为列表,获取产品,然后再返回字典:
import itertools
list_1 = [{'Name': 'John' , 'Age': 25} , {'Name': 'Mary' , 'Age': 15}]
list_2 = [{'Product': 'Car', 'Id': 1} , {'Product': 'TV' , 'Id': 2}]
l1 = [l.items() for l in list_1]
l2 = [l.items() for l in list_2]
print [dict(l[0] + l[1]) for l in itertools.product(l1, l2)]
输出是:
[{'年龄':25,'Id':1,'姓名':'约翰','产品':'汽车'},{'年龄':25,'身份':2,'姓名':'约翰','产品':'电视'},{'年龄':15,'Id':1,'姓名':'玛丽','产品':'汽车'},{'年龄':15,'我的':2,'姓名':'玛丽','产品':'电视'}]
如果这对你来说不够内存,那么试试:
for l in itertools.product(l1.iteritems() for l1 in list_1,
l2.iteritems() for l2 in list_2):
# work with one product at a time
对于Python 3:
import itertools
list_1 = [{'Name': 'John' , 'Age': 25} , {'Name': 'Mary' , 'Age': 15}]
list_2 = [{'Product': 'Car', 'Id': 1} , {'Product': 'TV' , 'Id': 2}]
print ([{**l[0], **l[1]} for l in itertools.product(list_1, list_2)])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.