Search code examples
pythonlistdictionaryfor-loopzip

How to iterate through 2 zipped list of dictionaries under certain conditions?


There are 4 list of dictionaries, the first two need to be added to the database, the second 2 already exist in the database:

to_add1 = [{'name': 'Kate', 'age': 25, 'id': 1234},
           {'name': 'Claire', 'age': 25, 'id': 4567},
           {'name': 'Bob', 'age': 25, 'id': 8910}]

to_add2 = [{'pets': 5, 'name_id': 1234},
           {'pets': 0, 'name_id': 4567},
           {'pets': 0, 'name_id': 8910}]

existing1 = [{'name': 'John', 'age': 50, 'id': 0000},
             {'name': 'Claire', 'age': 25, 'id': 4567}]
existing2 = [{'pets': 2, 'name_id': 0000},
             {'pets': 0, 'name_id': 4567}]

I would like to add to the database or in this reproducible example, print only the items that do not contain the existing1['name'] value in existing1. So in this case: Kate and Bob from to_add1 should be printed once. Due to the double loop, I am getting repetitions. How can I loop through all these dictionaries and print the items that do have a matching name to the names ofexisting 1 without repetitions ?

My code:

for person_to_add, pet_to_add in zip(to_add1, to_add2):
    for existing_person, existing_pet in zip(existing1, existing2):
        if person_to_add['name'] not in existing_person['name']:
            print(person_to_add)

Current output:

{'name': 'Kate', 'age': 25, 'id': 1234}
{'name': 'Kate', 'age': 25, 'id': 1234}
{'name': 'Claire', 'age': 25, 'id': 4567}
{'name': 'Bob', 'age': 25, 'id': 8910}
{'name': 'Bob', 'age': 25, 'id': 8910}

Desired output:

{'name': 'Kate', 'age': 25, 'id': 4567}
{'name': 'Bob', 'age': 25, 'id': 8910}

Solution

  • Depending on the complexity of the actual underlying query this might not work. But here is a solution taking advantage of the list of dictionary structure you are using. It is unclear exactly to me why you would need to use zip.

    a = [person_to_add for person_to_add in to_add1 if person_to_add['name'] not in [existing_person['name'] for existing_person in existing1]]
    

    This uses list comprehensions which should be pretty fast. The output 'a' would be in the same format as all your other data i.e a list of dicts. Do let me know if you need a further breakdown on how the list comprehension works.