Python 在比较另两个dict列表时,更新dictionary在dict列表中
我有两个字典列表,当某个键匹配时,我希望它将第一个列表中的dict附加到第二个列表中,但当字典变大时,需要很长时间。有没有更快的方法Python 在比较另两个dict列表时,更新dictionary在dict列表中,python,list,dictionary,Python,List,Dictionary,我有两个字典列表,当某个键匹配时,我希望它将第一个列表中的dict附加到第二个列表中,但当字典变大时,需要很长时间。有没有更快的方法 with open('tables', 'rb') as fp: tables = pickle.load(fp) # embedding for table in tables: filename = table + "_constraints" with open(filename, 'rb') as fp: fkeys
with open('tables', 'rb') as fp:
tables = pickle.load(fp)
# embedding
for table in tables:
filename = table + "_constraints"
with open(filename, 'rb') as fp:
fkeys = pickle.load(fp)
if fkeys and len(fkeys) == 1:
key = fkeys[0][1]
rkey = fkeys[0][2]
rtable = fkeys[0][3]
filename = table + ".json"
with open(filename, 'rb') as fp:
child = list(json.load(fp))
filename = rtable + ".json"
with open(filename, 'rb') as fp:
parent = list(json.load(fp))
for dict in child:
for rdict in parent:
if dict[key] == rdict[rkey]:
if "embed_"+table not in rdict:
rdict["embed_"+table] = []
del dict[key]
rdict["embed_"+table].append(dict)
break
输入示例如下:
tables = [child, parent]
child = [{child_id : 1, child_name : matthew , parent_id: 1},
{child_id : 2, child_name : luke , parent_id: 1},
{child_id : 3, child_name : mark , parent_id: 2}]
parent = [{parent_id:1, parent_name: john},
{parent_id:2, parent_name: paul},
{parent_id:3, parent_name: titus}]
parent = [{parent_id:1, parent_name: john, child_embed:[{child_id : 1, child_name : matthew },{child_id : 2, child_name : luke}]},
{parent_id:2, parent_name: paul, chiled_embed : [{child_id : 3, child_name : mark}]},
{parent_id:3, parent_name: titus}]
产出将是:
tables = [child, parent]
child = [{child_id : 1, child_name : matthew , parent_id: 1},
{child_id : 2, child_name : luke , parent_id: 1},
{child_id : 3, child_name : mark , parent_id: 2}]
parent = [{parent_id:1, parent_name: john},
{parent_id:2, parent_name: paul},
{parent_id:3, parent_name: titus}]
parent = [{parent_id:1, parent_name: john, child_embed:[{child_id : 1, child_name : matthew },{child_id : 2, child_name : luke}]},
{parent_id:2, parent_name: paul, chiled_embed : [{child_id : 3, child_name : mark}]},
{parent_id:3, parent_name: titus}]
如果我正确地阅读了问题,这应该可以满足您的需要
for entry in child:
p_id = entry['parent_id']
parent_update = [x for x in parent if x['parent_id'] == p_id][0]
position = parent.index(parent_update)
del entry['parent_id']
if 'child_embed' in list(parent_update.keys()):
parent_update['child_embed'] = parent_update['child_embed'] + [entry]
else:
parent_update['child_embed'] = [entry]
parent[position] = parent_update
print(parent)
其中:
[{'parent_id': 1, 'parent_name': 'john', 'child_embed': [{'child_id': 1, 'child_name': 'matthew'}, {'child_id': 2, 'child_name': 'luke'}]}, {'parent_id': 2, 'parent_name': 'paul', 'child_embed': [{'child_id': 3, 'child_name': 'mark'}]}, {'parent_id': 3, 'parent_name': 'titus'}]
当你做这样的循环时:
for dict in child:
for rdict in parent:
您正在设置O(n²)操作。对于每个孩子,您可以潜在地搜索每个家长。如果有1000个孩子和1000个父母,那就有一百万个循环。当然,您可以提前中断,但它不会改变函数相对于列表中数字的增长率
你应该花时间制作一个物体,让你以同样的速度找到你需要的东西,不管它有多大。在Python中,这是dict
。您可以通过一个循环将父列表转换为dict:
>> parent_d = {d['parent_id']: {'name': d['parent_name']} for d in parent}
>> print(parent_d)
{1: {'name': 'john'}, 2: {'name': 'paul'}, 3: {'name': 'titus'}}
这样,您就可以查找父项,而无需每次遍历整个列表:
>> parent_d[1]
{'name': 'john'}
有了它,您可以循环一次子项并将它们添加到父项中(如果密钥是新的,则使用setdefault
是初始化列表的一种简便方法):
现在,您有了一个清晰的字典,其中包含所有键入到父级的信息:
{ 1: {'name': 'john','child_embed': [{'child_id': 1, 'child_name': 'matthew'},{'child_id': 2, 'child_name': 'luke'}]},
2: {'name': 'paul', 'child_embed': [{'child_id': 3, 'child_name': 'mark'}]},
3: {'name': 'titus'}}
这是一种很好的格式。如果需要返回列表以匹配旧格式,可以使用列表理解:
>> [{'parent_id':i, **rest} for i, rest in parent_d.items()]
[{'parent_id': 1,
'name': 'john',
'child_embed': [{'child_id': 1, 'child_name': 'matthew'},
{'child_id': 2, 'child_name': 'luke'}]},
{'parent_id': 2,
'name': 'paul',
'child_embed': [{'child_id': 3, 'child_name': 'mark'}]},
{'parent_id': 3, 'name': 'titus'}]
那么你的问题是什么?对不起,我想知道是否有更快的方法。在中编辑。欢迎使用SO。除非你在这里描述,否则“某个键”只有你知道。那把钥匙是什么?给出示例输入和它的预期输出。编辑示例中关于速度的主要问题是,您使用的是应该使用dicts的列表。您的父母和孩子都有唯一的ID,因此您应该将dict键控到这些ID。然后您可以在固定时间内查找。