I'm struggling to create a new list based on two input lists. Here's an example: data_1 = [ { "title": "System", "priority": "medium", "subtitle": "mason", "files": [ {"name": "mason", "path": "/tmp/mason/mason.json"}, {"name": "mason", "path": "/tmp/mason/build.json"} ]}, { "title": "System", "priority": "medium", "subtitle": "kylie", "files": [ {"name": "kylie", "path": "/tmp/kylie/build.tar"}, {"name": "kylie", "path": "/tmp/kylie/kylie.json"} ]} ] data_2 = [ { "title": "System", "priority": "medium", "files": [ {"name": "build", "path": "/tmp/kylie/build.tar"}, {"name": "kylie", "path": "/tmp/kylie/kylie.json"}, {"name": "mason", "path": "/tmp/mason/mason.json"}, {"name": "build", "path": "/tmp/mason/build.json"} ]} ] merged = [ { "title": "System", "priority": "medium", "subtitle": "mason", "files": [ {"name": "mason", "path": "/tmp/mason/mason.json"}, {"name": "build", "path": "/tmp/mason/build.json"} ]}, { "title": "System", "priority": "medium", "subtitle": "kylie", "files": [ {"name": "build", "path": "/tmp/kylie/build.tar"}, {"name": "kylie", "path": "/tmp/kylie/kylie.json"} ]} ]  Basically, it would be OK to keep data from data_1 list and just replace files.name with the names coming from data_2 list, having the same path. Or multiply the element in data_2, assigning a subtitle and deleting all data_2.files items that don't match the paths specified in data_1 list. Anyway, I started doing something like: for d1 in data_1: for d2 in data_2: d1_key = (d1.get("title"), d1.get("priority")) d2_key = (d1.get("title"), d1.get("priority")) if d1_key == d2_key: for df in d1.get("files"): if any(df.get("path") in entry.get("path") for entry in d2.get("files")): print("Help! There must be easier way!")  And I don't think it's clear enough to get into this further. Would you suggest any other way to get the merged list created?
You can create a reverse mapping that maps paths in data_2 to names, and iteratively modify all names in data_1 with the paths mapped with the mapping: from itertools import chain from operator import itemgetter name_of = dict( map( itemgetter('path', 'name'), chain.from_iterable(map(itemgetter('files'), data_2)) ) ) for record in data_1: for file in record['files']: file['name'] = name_of[file['path']]  data_1 becomes: [{'title': 'System', 'priority': 'medium', 'subtitle': 'mason', 'files': [{'name': 'mason', 'path': '/tmp/mason/mason.json'}, {'name': 'build', 'path': '/tmp/mason/build.json'}]}, {'title': 'System', 'priority': 'medium', 'subtitle': 'kylie', 'files': [{'name': 'build', 'path': '/tmp/kylie/build.tar'}, {'name': 'kylie', 'path': '/tmp/kylie/kylie.json'}]}]  You can deepcopy data_1 to a new list named merged first if you prefer not to modify data_1. Demo here