SSeb
SSeb

Reputation: 7

Is there a better way to iterate through the keys in a dictionary inside a loop?

I have a script that calculates the nutritional information of a recipe. The user inputs the names of the ingredients, the proportion of the ingredients in grams, and supplies a .txt file where the nutritional information for each ingredient is stored (per 100g) which is actually a dictionary whose keys are the ingredients and the different values (kcal, kj, fat, etc) are lists inside each key. So as an example let's say the ingredients are eggplant, olive oil and lemon juice.

The script would have the following info so far:

nutrition_dict = {'kcal': 0, 'kj': 0, 'fat': 0, 'saturated fat': 0, 'carbohydrates': 0, 'sugar': 0, 'protein': 0, 'salt': 0}
nutrition_file = {'eggplant':[24, 100, 0.2, 0, 5.7, 2.4, 1, 0.005], 'olive oil':[884, 3701, 100, 13.8, 0, 0, 0, 0.005], 'lemon juice':[25, 105, 0, 0, 8.6, 2.4, 0.4, 0.0025]}
amount_of_ingredients = {'eggplant': 300, 'olive oil': 20, 'lemon juice': 5}
total_desired_recipe = 325

Now what I need to do is to:

My script works, but it is very ugly and improving it would make me learn better ways to get the desired results.

for key in nutrition_file:
    i = 0
    for i in range(8):
        if i == 0:
            nutrition_dict['kcal'] = nutrition_dict['kcal'] + nutrition_file[key][i]
        elif i == 1:
            nutrition_dict['kj'] = nutrition_dict['kj'] + nutrition_file[key][i]
        elif i == 2:
            nutrition_dict['fat'] = nutrition_dict['fat'] + nutrition_file[key][i]
        elif i == 3:
            nutrition_dict['saturated fat'] = nutrition_dict['saturated fat'] + nutrition_file[key][i]
        elif i == 4:
            nutrition_dict['carbohydrates'] = nutrition_dict['carbohydrates'] + nutrition_file[key][i]
        elif i == 5:
            nutrition_dict['sugar'] = nutrition_dict['sugar'] + nutrition_file[key][i]
        elif i == 6:
            nutrition_dict['protein'] = nutrition_dict['protein'] + nutrition_file[key][i]
        elif i == 7:
            nutrition_dict['salt'] = nutrition_dict['salt'] + nutrition_file[key][i]
        i += 1

    for key, value in nutrition_dict.items():
        print("The total of {} is: {:.2f}".format(key, value))
        nutrition = (value * 100) / total_desired_recipe
        print("The amount of {} per 100g is: {:.2f}".format(key, nutrition))
        i += 1

So my question is: Is there a better way to iterate through the nutrition_dict keys?

I would also like the print statements to be 'total information' and iterate through everything, then 'per 100g information' and iterate through everything. I don't like the current 'total, per 100g, total, per 100g'

Upvotes: 0

Views: 131

Answers (3)

rhurwitz
rhurwitz

Reputation: 2737

In terms of iteration, Python has many great ways to streamline list processing. In fact, much of your looping code can by eliminating some of "overhead" typical of other programming languages:

for food_type in nutrition_file:
    for index, metric in enumerate(nutrition_dict):
        nutrition_dict[metric] += nutrition_file[food_type][index]

    # Unchanged from OP's example
    for key, value in nutrition_dict.items():
        print("The total of {} is: {:.2f}".format(key, value))
        nutrition = (value * 100) / total_desired_recipe
        print("The amount of {} per 100g is: {:.2f}".format(key, nutrition))

Upvotes: 0

C.Nivs
C.Nivs

Reputation: 13106

There is, you probably want to just zip the nutrition_dict keys with the values from each food in nutrition_file:

for k, *v in zip(nutrition_dict, *nutrition_file.values()):
    print(k, v)

kcal [24, 884, 25]
kj [100, 3701, 105]
fat [0.2, 100, 0]
saturated fat [0, 13.8, 0]
carbohydrates [5.7, 0, 8.6]
sugar [2.4, 0, 2.4]
protein [1, 0, 0.4]
salt [0.005, 0.005, 0.0025]

Then all you need to do is collect totals:

for k, *v in zip(nutrition_dict, *nutrition_file.values()):
    nutrition_dict[k] = sum(v)


nutrition_dict
{'kcal': 933, 'kj': 3906, 'fat': 100.2, 'saturated fat': 13.8, 'carbohydrates': 14.3, 'sugar': 4.8, 'protein': 1.4, 'salt': 0.0125}

Upvotes: 2

ScienceSnake
ScienceSnake

Reputation: 617

The thing you're looking for is enumerate, which lets you (in this case) go through the keys of a dictionary while numbering them in order at the same time. Complete solution is

for index, key in enumerate(nutrition_dict):
    for ingredient_name, ingredient_amount in amount_of_ingredients.items():
        nutrition_dict[key] += ingredient_amount * nutrition_file[ingredient_name][index]

    print("The total of {} is: {:.2f}".format(key, nutrition_dict[key]))
    nutrition = (nutrition_dict[key] * 100) / total_desired_recipe
    print("The amount of {} per 100g is: {:.2f}".format(key, nutrition))

As an aside, kJ and kcal are the same quantity in different units (a factor is 4.184), so there's no need to keep track of both.

Upvotes: 0

Related Questions