Summing only one value of list in case of repeat and transform it into a dictionary

Viewed 24

Stackoverflow, hello

I have a problem, which I almost solved, however, I have no idea in making last step.

So, in the initial list there are two almost identical elements ('Tomato', 3, 'PCS') and ('Tomato', 2, 'PCS'), in which only the middle parameter (quantity) is different and in the end it should be a sum of these two quantities. In the end I should sum 3 and 2. I will describe and it would be more easy to understand:

So, initial list is:

initial = [('Egg', 2, 'PCS'), ('Milk', 100, 'ml'), ('Tomato', 3, 'PCS'), ('Beef', 500, 'g'), ('Sweet pepper', 1, 'PCS'), ('Pita bread', 2, 'PCS'), ('Wine vinegar', 1, 'tbsp'), ('Tomato', 2, 'PCS')]

And in the end I should recieve:

{'Beef': {'measure': 'g', 'quantity': 500},
 'Egg': {'measure': 'PCS', 'quantity': 2},
 'Milk': {'measure': 'ml', 'quantity': 100},
 'Pita bread': {'measure': 'PCS', 'quantity': 2},
 'Sweet pepper': {'measure': 'PCS', 'quantity': 1},
 'Tomato': {'measure': 'PCS', 'quantity': 5},
 'Wine vinegar': {'measure': 'tbsp', 'quantity': 1}}

But in the last but one line I recieve 'Tomato': {'measure': 'PCS', 'quantity': 2}, because the last element in the list just replacing the element with similar characteristics, not summing "quantity".

And the result I have is:

{'Beef': {'measure': 'g', 'quantity': 500},
 'Egg': {'measure': 'PCS', 'quantity': 2},
 'Milk': {'measure': 'ml', 'quantity': 100},
 'Pita bread': {'measure': 'PCS', 'quantity': 2},
 'Sweet pepper': {'measure': 'PCS', 'quantity': 1},
 'Tomato': {'measure': 'PCS', 'quantity': 2},
 'Wine vinegar': {'measure': 'tbsp', 'quantity': 1}}

My code is:

for elems2 in initial:
    dinit = {'measure': elems2[2], 'quantity': elems2[1]}
    d = {}.fromkeys([elems2[0]], dinit)
    new_book[elems2[0]] = dinit
pprint(new_book)

Could somebody help me to solve the problem of summing "the quantity" - element inside the element of the list?

2 Answers

You may use a simple for loop:

result = {}
for item in initial:
    key, quantity, measure = item
    if key in result:
        result[key]["quantity"] += quantity
    else:
        result[key] = {"measure": measure, "quantity": quantity}

print(result)

This yields

{'Egg': {'measure': 'PCS', 'quantity': 2}, 
 'Milk': {'measure': 'ml', 'quantity': 100}, 
 'Tomato': {'measure': 'PCS', 'quantity': 5}, 
 'Beef': {'measure': 'g', 'quantity': 500}, 
 'Sweet pepper': {'measure': 'PCS', 'quantity': 1}, 
 'Pita bread': {'measure': 'PCS', 'quantity': 2}, 
 'Wine vinegar': {'measure': 'tbsp', 'quantity': 1}}

You could do:

from collections import defaultdict
import pprint

initial = [('Egg', 2, 'PCS'), ('Milk', 100, 'ml'), ('Tomato', 3, 'PCS'), ('Beef', 500, 'g'), ('Sweet pepper', 1, 'PCS'),
           ('Pita bread', 2, 'PCS'), ('Wine vinegar', 1, 'tbsp'), ('Tomato', 2, 'PCS')]

# count the measures by ingredient
counts = defaultdict(int)
for ingredient, quantity, measure in initial:
    counts[(ingredient, measure)] += quantity

result = {ingredient: {'measure': measure, 'quantity': quantity} for (ingredient, measure), quantity in counts.items()}

pprint.pprint(result)

Output

{'Beef': {'measure': 'g', 'quantity': 500},
 'Egg': {'measure': 'PCS', 'quantity': 2},
 'Milk': {'measure': 'ml', 'quantity': 100},
 'Pita bread': {'measure': 'PCS', 'quantity': 2},
 'Sweet pepper': {'measure': 'PCS', 'quantity': 1},
 'Tomato': {'measure': 'PCS', 'quantity': 5},
 'Wine vinegar': {'measure': 'tbsp', 'quantity': 1}}
Related