<p>将这两个对象视为各自列表中的元素可能会有所帮助。可能您还有其他具有不同<code>name</code>值的对象,例如可能来自JSON格式的REST请求</p>
<p>然后可以对<code>name</code>和<code>id</code>键执行<a href="https://en.wikipedia.org/wiki/Join_(SQL)#Left_outer_join" rel="nofollow noreferrer">left outer join</a>:</p>
<pre><code>#!/usr/bin/env python
a = [
{
"name": "harry",
"properties": [
{
"id":"N3",
"status":"OPEN",
"type":"energetic"
},
{
"id":"N5",
"status":"OPEN",
"type":"hot"
}
]
}
]
b = [
{
"name": "harry",
"properties": [
{
"id":"N3",
"type":"energetic",
"language": "english"
},
{
"id":"N6",
"status":"OPEN",
"type":"cool"
}
]
}
]
a_names = set()
a_prop_ids_by_name = {}
a_by_name = {}
for ao in a:
an = ao['name']
a_names.add(an)
if an not in a_prop_ids_by_name:
a_prop_ids_by_name[an] = set()
for ap in ao['properties']:
api = ap['id']
a_prop_ids_by_name[an].add(api)
a_by_name[an] = ao
res = []
for bo in b:
bn = bo['name']
if bn not in a_names:
res.append(bo)
else:
ao = a_by_name[bn]
bp = bo['properties']
for bpo in bp:
if bpo['id'] not in a_prop_ids_by_name[bn]:
ao['properties'].append(bpo)
res.append(ao)
print(res)
</code></pre>
<p>上面的想法是处理列表<code>a</code>中的名称和ID。按名称列出的名称和ID是Python <code>set</code>的实例。所以成员总是独一无二的</p>
<p>一旦有了这些集合,就可以对列表<code>b</code>的内容执行左外部联接</p>
<p>或者<code>b</code>中有一个对象在<code>a</code>中不存在(即共享一个公共的<code>name</code>),在这种情况下,您可以按原样将该对象添加到结果中。但是如果在<code>b</code>中有一个对象确实存在于<code>a</code>(它共享一个公共的<code>name</code>),那么您将迭代该对象的<code>id</code>值,并按名称查找尚未在<code>a</code>ID集中的ID。将缺少的属性添加到<code>a</code>,然后将处理过的对象添加到结果中</p>
<p>输出:</p>
<pre><code>[{'name': 'harry', 'properties': [{'id': 'N3', 'status': 'OPEN', 'type': 'energetic'}, {'id': 'N5', 'status': 'OPEN', 'type': 'hot'}, {'id': 'N6', 'status': 'OPEN', 'type': 'cool'}]}]
</code></pre>
<p>这不会对输入执行任何错误检查。这依赖于每个对象的<code>name</code>值是唯一的。因此,如果两个列表中的对象中都有重复的键,则可能会得到垃圾(不正确或意外的输出)</p>