I'll try to be the more concise that I can.
Two dictionary lists as follows:
dictlist1 = [{'name': 'john', 'age': 30}, {'name': 'jessica', 'age': 56}, {'name': 'kirk', 'age': 20}, {'name': 'mario, 'age': 25}]
dictlist2 = [{'name': 'john', 'job': 'engineer'}, {'name': 'jessica', 'job':'nurse'}, {'name': 'mario', 'job': 'electrician'}]
My objective is to match base on the key "name" on both dictionaries and, at the end, create a third dictionary list with the key that has no match, in this case {'name':'kirk', 'age':20}, like this:
listfinal = [{'name': 'kirk', 'age': 20}]
I've tried successfully compare the equal keys, creating a new dictionary with keys that matches and adding "job" key to it, doing this:
for dict2 in dictlist2:
for dict1 in dictlist1:
if dict1['name'] == dict2['name']:
matchname1 = dict2['name']
dictoutput = {'name': matchname1, 'age': dict1['age'], 'group': dict2['group']}
templist.append(dictoutput)
for dictionay in templist:
print(dictionay)
Output:
{'name': 'john', 'age': '30', 'job': 'engineer'}
{'name': 'jessica', 'age': '56', 'job': 'nurse'}
{'name': 'mario', 'age': '25', 'job': 'electrician'}
But absolutely no luck to get kirk user alone, not even using "else" in the inner if statement or creating a new if statement and using not equal (.=). I always get all the users when printing.
Any orientation will be highly appreciated.
Enumerate the lists and then collect the indices of matched pairs in a list inside the loop and delete corresponding elements outside the loop.
matched_d1 = []
matched_d2 = []
for j2, dict2 in enumerate(dictlist2):
for j1, dict1 in enumerate(dictlist1):
if dict1['name'] == dict2['name']:
matchname1 = dict2['name']
dictoutput = {'name': matchname1, 'age': dict1['age'], 'group': dict2['group']}
templist.append(dictoutput)
matched_d1.append(j1)
matched_d2.append(j2)
for j in sorted(matched_d1, reverse = True):
dictlist1.pop(j)
for j in sorted(matched_d2, reverse = True):
dictlist2.pop(j)
ans = dictlist1 + dictlist2
you can use set operations to get the unique name, first make a set of the names on each one and subtract both, then use that to get the appropriate item form the list
>>> name1 = set(d["name"] for d in dictlist1)
>>> name2 = set(d["name"] for d in dictlist2)
>>> name1 - name2
{'kirk'}
>>> name2 - name1
set()
>>> unique = name1 - name2
>>> listfinal = [d for n in unique for d in dictlist1 if d["name"]==n]
>>> listfinal
[{'name': 'kirk', 'age': 20}]
>>>
Additionally, looking at @freude answers, you can make it a dictionary of name:index for each list an subtracts its keys, given that they dict.keys behave set-like in order to avoid a double loop from before to get the right item from the list
>>> name1 = {d["name"]:i for i,d in enumerate(dictlist1)}
>>> name2 = {d["name"]:i for i,d in enumerate(dictlist2)}
>>> unique = name1.keys() - name2.keys()
>>> unique
{'kirk'}
>>> [ dictlist1[name1[n]] for n in unique]
[{'name': 'kirk', 'age': 20}]
>>>
You can use sets
to find the names that are only in dictlist1
, in dictlist2
and also the common names. Then create the listfinal
by keeping only the item with the name
not in the common names:
dictlist1 = [{"name": "john", "age": 30}, {"name": "jessica", "age": 56}, {"name":"kirk" , "age": 20}, {"name": "mario", "age": 25}]
dictlist2 = [{"name": "john", "job": "engineer"}, {"name": "jessica", "job": "nurse"}, {"name": "mario", "job": "electrician"}]
names_dictlist1 = {item["name"] for item in dictlist1}
names_dictlist2 = {item["name"] for item in dictlist2}
common_names = names_dictlist1 & names_dictlist2
listfinal = [item for item in dictlist1 + dictlist2 if item["name"] not in common_names]
If you want one-line solution there it is
print([person for person in dictlist1 if person['name'] not in map(lambda x: x['name'], dictlist2)])
This code prints element from fist list wich "name" key doesnt occur in second list
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.