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!

+3


source to share


4 answers


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.

0


source


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'

      

0


source


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

      

0


source


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.

0


source







All Articles