0

After my for loop successfully returns the keys of my first set of nested dictionaries. I am getting this error:

for item in MENU[drink][ingredient_list]:
TypeError: 'float' object is not iterable

I need to get access to all of the key-value pairs so that I can perform operations on them, but this code gets stuck at 'espresso'.

 #3 levels deep nested dictionary
MENU = {
    "espresso": {
        "ingredients": {
            "water": 50,
            "coffee": 18,
        },
        "cost": 1.5,
    },
    "latte": {
        "ingredients": {
            "water": 200,
            "milk": 150,
            "coffee": 24,
        },
        "cost": 2.5,
    },
    "cappuccino": {
        "ingredients": {
            "water": 250,
            "milk": 100,
            "coffee": 24,
        },
        "cost": 3.0,
    }
}

#level one of the dictionary
for drink in MENU:
    #this should print the drinks and cost
    print(drink)
    #this should print the ingredients   
    for ingredient_list in MENU[drink]:
        print(ingredient_list)
        for item in MENU[drink][ingredient_list]: 
            print(item)
Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50
Barry Brewer
  • 63
  • 1
  • 5
  • When you do `for ingredient_list in MENU[drink]:`, what values do you expect `ingredient_list` to have each time through the loop? (What results do you see from `print(ingredient_list)`? Do you understand why?) Therefore, what values do you expect to get from `MENU[drink][ingredient_list]`? Does it make sense to do `for item in...` with that result, *every time* through the outer loop? – Karl Knechtel Jan 24 '22 at 13:32
  • Please read https://ericlippert.com/2014/03/05/how-to-debug-small-programs/. It is all well and good to `print(ingredient_list)` and see what is going on; but in order to learn something from that, you have to look at the results you get, think about them, and make sure you understand them. – Karl Knechtel Jan 24 '22 at 13:34
  • "#this should print the drinks and cost" Okay, so - it prints the drink, but it doesn't print the cost. Yes? So - given the drink name and the overall `MENU`, how do you get the dict with information about the drink? Given that dict, how do you get the cost? (Hint: there is no looping involved here; just directly access values.) – Karl Knechtel Jan 24 '22 at 13:36
  • Karl, thank you. I appreciate the link. I get it. I want to make sure we saying the same thing. When I mention "cost" I mean the key:value pair named "cost" indexed at [1], [3] & [5] of dict MENU. I am sure you understand but just want to be clear. You wrote a cool snippet below but it doesn't list "cost", it puts the cost next to the drink. That is where I am totally confused. I do my debugging Thonny and it really helps to see what is going on. To try and see what it happening, but it's like the k:v pair "cost" is just getting ignored. – Barry Brewer Jan 26 '22 at 03:08
  • I didn't write a snipped, I edited someone else's answer for clarity. "but it doesn't list "cost", it puts the cost next to the drink." It's not clear *what you want the exact output to be, for this input*. Ultimately, you need to deal with the fact that *the depth of your data is not consistent*. For each menu item, `"ingredients"` holds a nested dict, but `"cost"` does not. – Karl Knechtel Jan 26 '22 at 07:37
  • "I mean the key:value pair named "cost" indexed at [1], [3] & [5] of dict MENU." There is **not any such thing**. The indices are `["espresso"]["cost"]`, `["latte"]["cost"]` and `["cappucino"]["cost"]`, and the corresponding values are `1.5`, `2.5` and `3.0`. – Karl Knechtel Jan 26 '22 at 07:38
  • Thanks, Karl. Apparently I really don't understand the structure of the dictionary, which is the fundamental problem. I thought the key : value pairs of dict MENU were "espresso" : value, "cost" : value, 'latte' : value, 'cappuccino' ; value, but from what you wrote it seems like 'cost' is a part of 'espresso' etc...I printed (["espresso"]["cost"]) and seem to understand more clearly what you have been driving at. I really appreciate your feedback on this. Do you have a preferred resource you recommend to review dictionary stuctures? – Barry Brewer Jan 26 '22 at 12:29

3 Answers3

1

You are iterating over cost as well. Try this:

#level one of the dictionary
for drink, data in MENU.items():
    #this should print the drinks and cost
    print(drink, data["cost"])
    #this should print the ingredients   
    for ingredient in data["ingredients"].items():
        print(ingredient)
Bharel
  • 23,672
  • 5
  • 40
  • 80
  • Thank you. I have seen the method .items() around, but am not familiar enough with it. I will now watch some vids and play around with your code to see if I can get a grip on it. – Barry Brewer Jan 26 '22 at 02:51
0

As Bharel suggested, if you just iterate the dict MENU python will by default iterate only the keys - this is why the code works if you just run:

for drink in MENU:
   #this should print the drinks and cost
   print(drink)

But it will raise an exception when you try the second for loop, because you are not iterating the values, to iterate both values and keys use MENU.items() as Bharel suggested.

for key, value in MENU.items():
   #this should print the drinks and cost
   print(key, value["cost"])
   #this should print the ingredients   
   for key_i, value_i in value["ingredients"].items():
       print(key_i, value_i)
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
0

Your dictionary is not a complete 3 level one. It has just 2 complete levels. For example MENU['espresso']['cost'] is equal to 1.5, so you can not iterate on it.

MENU = {
    "espresso": {
        "ingredients": {
            "water": 50,
            "coffee": 18,
        },
        "cost": {
            "normal": 1.5,
            "vip": 4.5,
        }
    },
    "latte": {
        "ingredients": {
            "water": 200,
            "milk": 150,
            "coffee": 24,
        },
        "cost": {
            "normal": 2.5,
            "vip": 6.5,
        }
    },
    "cappuccino": {
        "ingredients": {
            "water": 250,
            "milk": 100,
            "coffee": 24,
        },
        "cost": {
            "normal": 3,
            "vip": 4.1,
        }
    }
}
Happy Ahmad
  • 1,072
  • 2
  • 14
  • 33