Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在比较另两个dict列表时,更新dictionary在dict列表中_Python_List_Dictionary - Fatal编程技术网

Python 在比较另两个dict列表时,更新dictionary在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

我有两个字典列表,当某个键匹配时,我希望它将第一个列表中的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 = 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。然后您可以在固定时间内查找。