Abdulelah
Abdulelah

Reputation: 691

compare two list of dicts in python 2

I want to compare two lists of dictionaries in python, I have a list sent from the frontend and a query result stored in the same function, so all I want is to compare both of the lists with the key barcode and if they matches I want to append the name from the second dictionary to the first one

for example:

data_from_frontend = [
    { barcode: '1', name_en: 'milk' },
    { barcode: '2', name_en: 'water' },
    { barcode: '3', name_en: 'cheese' },
    { barcode: '10', name_en: 'pepsi' },
]
result_from_query = [
    { barcode: '1', name: 'PID012343' },
    { barcode: '2', name: 'PID123454' },
    { barcode: '10', name: 'PID123432' },
]

I want to compare both of the lists and by the barcode and if they match I want to merge the the pair of both variables to a new one + adding the one the doesn't match to another list, so the outcome would be two new variables with the [matched + name] and not_found, how can I achieve that ?

Here is what i've tried

equal = []
not_equal = []
no_barcode = []
x = [ { "age": "22" }, { "name": "John Doe" }, { "name": "Jane Doe" }, { "name": "Doctor" }, { "name": "Engineer" } ]
y = [ { "name": "Engineer" }, { "name": "Jane Doe" }, { "name": "Doctor" } ]
x_sort = sorted(x, key=lambda k: ("name" not in k, k.get("name", None)))
y_sort = sorted(y, key=lambda k: ("name" not in k, k.get("name", None)))
print(y_sort)
for x_val in x_sort:
    if "name" not in x_val.keys():
        no_barcode.append(x_val)
    else:
        for y_val in y_sort:
            if x_val["name"] == y_val["name"]:
                equal.append(x_val)
                mapped = map(lambda k: k["name"], y_sort)
                if x_val["name"] not in mapped:
                    not_equal.append(x_val)
print('equal')
print(equal)
print('not equal')
print(not_equal)

Upvotes: 0

Views: 92

Answers (2)

chashikajw
chashikajw

Reputation: 828

Your barcode matching results can be get like this.

barcode = 'barcode'
name_en = 'name_en'
name = 'name'

matching_result = data_from_frontend[:] #get a copy of front end data to use as the output

for i in range(len(data_from_frontend)):
    for j in range(len(result_from_query)):
        if(data_from_frontend[i][barcode] == result_from_query[j][barcode]):
            matching_result[i][name] = result_from_query[j][name]
            break

print(matching_result)

Upvotes: 0

Pavel Sokolov
Pavel Sokolov

Reputation: 104

First of all you should fix your dict keys and enclose them into quotes.

Then you can use generator expression to find items, for example:

print('initial dict:')
pprint.pprint(data_from_frontend)

for item in result_from_query:
    item_found = next((i for i in data_from_frontend if i['barcode'] == item['barcode']), False)
    if item_found:
        item_found['name'] = item['name']

print('dict after search:')
pprint.pprint(data_from_frontend)

will produce:

initial dict:
[{'barcode': '1', 'name_en': 'milk'},
 {'barcode': '2', 'name_en': 'water'},
 {'barcode': '3', 'name_en': 'cheese'},
 {'barcode': '10', 'name_en': 'pepsi'}]
dict after search:
[{'barcode': '1', 'name': 'PID012343', 'name_en': 'milk'},
 {'barcode': '2', 'name': 'PID123454', 'name_en': 'water'},
 {'barcode': '3', 'name_en': 'cheese'},
 {'barcode': '10', 'name': 'PID123432', 'name_en': 'pepsi'}]

Using False in generator will avoid error when searching by barcode value not existing in target dict.

P.S. dont forget to import pprint if you want to use it

P.P.S. and sure you can create new dict instead of modifying existing one, using same logic

Upvotes: 1

Related Questions