簡體   English   中英

多個詞典列表的笛卡爾積

[英]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)

這里的關鍵是利用dictsupdate功能來添加成員。 此版本將保留父級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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM