Home > Blockchain >  Python: Finding duplicate dictionary values from two lists of dictionaries
Python: Finding duplicate dictionary values from two lists of dictionaries

Time:01-07

I wanted to build a simple python script that could add all the items from multiple recipes into an excel document to make shopping and sticking to a meal plan easier. I was able to get a simple version working, however when it exports to excel if multiple recipes have the same ingredient it will have it in the excel document multiple times. I have been trying to instead have it add the quantity of that ingredient together instead of repeating it. Below is a sample of two recipe ingredients.

import pandas as pd

friedRiceShrimp = [
    {"Ingredient": "Garlic clove", "Size": "clove", "Quantity": 3, "Aisle": "Produce"},
    {"Ingredient": "Instant Brown Rice", "Size": "oz", "Quantity": 16, "Aisle": 22},
    {"Ingredient": "Soy Sauce", "Size": "tbsp", "Quantity": 2, "Aisle": 22},
    {"Ingredient": "Chili Paste", "Size": "tbsp", "Quantity": 2, "Aisle": 22},
    {"Ingredient": "Honey", "Size": "tbsp", "Quantity": 1, "Aisle": 18},
    {"Ingredient": "Peanut Oil", "Size": "tbsp", "Quantity": 2, "Aisle": 21},
    {"Ingredient": "Shrimp", "Size": "oz", "Quantity": 10, "Aisle": 12},
    {"Ingredient": "Egg", "Size": "individual", "Quantity": 3, "Aisle": "Dairy"},
    {"Ingredient": "Snap Peas", "Size": "cup", "Quantity": 1.5, "Aisle": "Produce"},
    {"Ingredient": "Peanuts Dry-Roasted", "Size": "cup", "Quantity": .3, "Aisle": 14}
]

macNCheese = [
    {"Ingredient": "Bacon", "Size": "Slice", "Quantity": 6, "Aisle": 8},
    {"Ingredient": "Chicken Stock", "Size": "cup", "Quantity": 2, "Aisle": 24},
    {"Ingredient": "Milk", "Size": "cup", "Quantity": 1, "Aisle": "Dairy"},
    {"Ingredient": "Butternut Squash puree", "Size": "oz", "Quantity": 10, "Aisle": "Produce"},
    {"Ingredient": "Macaroni Elbow Pasta", "Size": "oz", "Quantity": 10, "Aisle": 23},
    {"Ingredient": "Broccoli", "Size": "cup", "Quantity": 3, "Aisle": "Produce"},
    {"Ingredient": "Cheddar Cheese Shredded", "Size": "oz", "Quantity": 5, "Aisle": 8},
    {"Ingredient": "Garlic clove", "Size": "clove", "Quantity": 2, "Aisle": "Produce"}
]`

shopping_list = friedRiceShrimp   macNCheese
df = pd.DataFrame(data=shopping_list)
df.to_excel("Test.xlsx", index=False)

I tried the below and several different loops. My idea is to loop through shopping_list and with each item add it to a new list. If the item is already in the new list (and "Size" is the same) the quantity will be added together instead of having a duplicate item show up in my excel export. The issue I have is I matching just the Ingredient in idx compared to everything in final_list. I also am willing and understand that I may need to rework this from the ground up to make my final vision work.

shopping_list = friedRiceShrimp   macNCheese
final_list = []

for idx in shopping_list:
    if idx["Ingredient"] in final_list[0]["Ingredient"]: #needs to check if idx ingredent is already in list somehow
        final_list[0]["Quantity"]  = idx["Quantity"] #if that idx ingredent in final list add just quantity
    else:
        final_list.append(idx)
        print(idx["Ingredient"])

Thank you for the help and assistance, still learning python and trying to find ways to use it in my everyday life a bit more to help cement ideas and concepts.

CodePudding user response:

Essentially, you are trying to merge/roll up duplicated records with same ('Ingredient', 'Size') attributes and sum up their Quantity.
Use pandas power to group by the needed columns and aggregate by other columns that need to be calculated or reduced.

shopping_list = friedRiceShrimp   macNCheese
df = pd.DataFrame(data=shopping_list)
df = df.groupby(['Ingredient', 'Size'], as_index=False).agg({'Quantity': 'sum', 'Aisle': 'first'})
print(df)

                 Ingredient        Size  Quantity    Aisle
0                     Bacon       Slice       6.0        8
1                  Broccoli         cup       3.0  Produce
2    Butternut Squash puree          oz      10.0  Produce
3   Cheddar Cheese Shredded          oz       5.0        8
4             Chicken Stock         cup       2.0       24
5               Chili Paste        tbsp       2.0       22
6                       Egg  individual       3.0    Dairy
7              Garlic clove       clove       5.0  Produce
8                     Honey        tbsp       1.0       18
9        Instant Brown Rice          oz      16.0       22
10     Macaroni Elbow Pasta          oz      10.0       23
11                     Milk         cup       1.0    Dairy
12               Peanut Oil        tbsp       2.0       21
13      Peanuts Dry-Roasted         cup       0.3       14
14                   Shrimp          oz      10.0       12
15                Snap Peas         cup       1.5  Produce
16                Soy Sauce        tbsp       2.0       22

CodePudding user response:

You could do it like this in Python


shopping_list = friedRiceShrimp   macNCheese
final_list = []

for ingredient_to_add in shopping_list:
    # returns the first dictionary that satisfies the condition for Ingredient name and size
    # returns None if there is no dictionary in final_list that satisfies the condition
    match = next((ingredient for ingredient in final_list if
                  ingredient['Ingredient'] == ingredient_to_add['Ingredient'] and ingredient['Size'] ==
                  ingredient_to_add['Size']), None)

    # if the ingredient already exists in final_list we add to the quantity of the existing element that of the new ingredient
    if match:
        match['Quantity']  = ingredient_to_add['Quantity']

    # otherwise we simply add the ingredient
    else:
        final_list.append(ingredient_to_add)
        

for ingredient in final_list:
    print(ingredient)

Output

{'Ingredient': 'Garlic clove', 'Size': 'clove', 'Quantity': 5, 'Aisle': 'Produce'}
{'Ingredient': 'Instant Brown Rice', 'Size': 'oz', 'Quantity': 16, 'Aisle': 22}
{'Ingredient': 'Soy Sauce', 'Size': 'tbsp', 'Quantity': 2, 'Aisle': 22}
{'Ingredient': 'Chili Paste', 'Size': 'tbsp', 'Quantity': 2, 'Aisle': 22}
{'Ingredient': 'Honey', 'Size': 'tbsp', 'Quantity': 1, 'Aisle': 18}
{'Ingredient': 'Peanut Oil', 'Size': 'tbsp', 'Quantity': 2, 'Aisle': 21}
{'Ingredient': 'Shrimp', 'Size': 'oz', 'Quantity': 10, 'Aisle': 12}
{'Ingredient': 'Egg', 'Size': 'individual', 'Quantity': 3, 'Aisle': 'Dairy'}
{'Ingredient': 'Snap Peas', 'Size': 'cup', 'Quantity': 1.5, 'Aisle': 'Produce'}
{'Ingredient': 'Peanuts Dry-Roasted', 'Size': 'cup', 'Quantity': 0.3, 'Aisle': 14}
{'Ingredient': 'Bacon', 'Size': 'Slice', 'Quantity': 6, 'Aisle': 8}
{'Ingredient': 'Chicken Stock', 'Size': 'cup', 'Quantity': 2, 'Aisle': 24}
{'Ingredient': 'Milk', 'Size': 'cup', 'Quantity': 1, 'Aisle': 'Dairy'}
{'Ingredient': 'Butternut Squash puree', 'Size': 'oz', 'Quantity': 10, 'Aisle': 'Produce'}
{'Ingredient': 'Macaroni Elbow Pasta', 'Size': 'oz', 'Quantity': 10, 'Aisle': 23}
{'Ingredient': 'Broccoli', 'Size': 'cup', 'Quantity': 3, 'Aisle': 'Produce'}
{'Ingredient': 'Cheddar Cheese Shredded', 'Size': 'oz', 'Quantity': 5, 'Aisle': 8}
  • Related