我倾向于同意@Aplet123 的评论,即 OP 的初始代码简洁易读。但是有一个重要的警告:它确实修改了listDicts1的字典,在我的书中这是一个很大的禁忌:想象一个毫无戒心的用户(你自己,在三个月内)一堆字典,将它们放在一个列表中并将其传递给您的函数,只是为了(后来,在调试和许多头疼的过程中)发现原始字典本身已被偷偷地修改为您的函数的副作用。 ..(我向你保证,这发生在最好的家庭中)。
因此,如果您希望保持初始 dicts 不变,这在更安全且恕我直言总是更可取的情况下,那么只要需要修改(当您的条件为 True 时),您就必须生成新的 dicts。
第 1 版:纯推导式(但也总是创建一个新的 dict):
listDicts3 = [{
**d,
**{'person': d.get('person', []) + [
d2 for d2 in listDicts2 if d['name'] in d2['text']
]}} for d in listDicts1]
第 2 版,首选:仅在需要时创建新的 dicts(其他只是通过引用复制):
persons = [[d2 for d2 in listDicts2 if d['name'] in d2['text']] for d in listDicts1]
listDicts3 = [
{**d, **dict(person=d.get('person', []) + p)} if p else d
for d, p in zip(listDicts1, persons)
]
请注意,如果person 还不是d 的成员,则上述两个列表都以空列表开头。
测试示例:
listDicts1 = [dict(name='fred', person=[]), dict(name='paul', person=[])]
listDicts2 = [dict(text='paul ate an apple'), dict(text='anne reads a book')]
# ... (one of the code snippets above to make listDicts3)
listDicts3
# output:
[{'name': 'fred', 'person': []},
{'name': 'paul', 'person': [{'text': 'paul ate an apple'}]}]
listDicts1
# out (shows it is unchanged)
[{'name': 'fred', 'person': []}, {'name': 'paul', 'person': []}]
# your code, with side-effect
for d in listDicts1:
for d2 in listDicts2:
if d['name'] in d2['text']:
d['person'].append(d2)
print(d)
# out:
{'name': 'fred', 'person': []}
{'name': 'paul', 'person': [{'text': 'paul ate an apple'}]}
# HOWEVER:
listDicts1
# out:
[{'name': 'fred', 'person': []},
{'name': 'paul', 'person': [{'text': 'paul ate an apple'}]}]
注意:您可以避免副作用并保持您的代码几乎原样:
for d in listDicts1:
d = d.copy()
for d2 in listDicts2:
if d['name'] in d2['text']:
d['person'].append(d2)
print(d)