Compare two lists of dictionaries
Let's say I have two lists of dictionaries:
a=[{'name':'A','color':'1'},
{'name':'B','color':'2'}]
b=[{'name':'A','color':'3'},
{'name':'c','color':'1'}]
I need something like this:
for i in a:
if i['name'] is not existent in b['name']:
do this.
else:
if i['color'] is < than the corresponding item in b list:
do that.
I don't know how to extract an item from the second list, which will cause the iteration to continue "else:".
I need to say that the first list is smaller (a few hundred pieces), but the second has several thousand dictionaries, each containing about a hundred items. Efficiency is very important.
I thought about making a list of all the values ββfor key ['name'] in both lists and comparing that, but that would mean repeating the first time to create those lists and then repeating over the lists for that, or do it. Thanks in advance!
source to share
Before you start, you absolutely want to iterate over b
. The only obvious alternative is to iterate over b
for each element in a
, which is obviously worse.
b_dict = {x['name']: x for x in b}
for item in a:
if item['name'] in b_dict:
f(b_dict['name'])
else:
pass # whatever
You might be interested get()
in the Python dictionaries method if you want to avoid using in
it and then get the item immediately.
source to share
You can use a hash table or something like this:
a=[{'name':'A','color':'1'},
{'name':'B','color':'2'}]
b=[{'name':'A','color':'3'},
{'name':'c','color':'1'}]
for item in a:
mach = list(filter(lambda x: x['name'] == item['name'], b))
if mach:
if int(item['color']) > int(mach[0]['color']):
do that
else:
do this
Dict in Python - a kind of hash table with amortized O (1) . Then you can change your code to this:
a=[{'name':'A','color':'1'},
{'name':'B','color':'2'}]
b=[{'name':'A','color':'3'},
{'name':'c','color':'1'}]
b_dict = {item['name']:item['color'] for item in b}
for item in a:
if item['name'] in b_dict and int(item['color']) < int(b_dict[item['name']]):
print 'do this'
else:
print 'do that'
source to share
First make an index:
a=[{'name':'A','color':'1'},
{'name':'B','color':'2'}]
b=[{'name':'A','color':'3'},
{'name':'c','color':'1'}]
dic = {}
for i,item in enumerate(b):
dic[item['name']] = i
# dic will be {'A':0,'c':1}
For item in a:
if not item['name'] in dic:
do this
else:
if b[dic[item['name']]]['color'] > item['color']:
do that
source to share
Instead of making a list of values ββfor both lists, do it only for list B. And then change the if condition to
if i['name'] is not existent in names_in_b:
You will need to test the performance gain of this method, but with this solution, you only need to iterate over B and then iterate over A.
source to share