嵌套的for循环遍历多个字典,有没有更简单的方法?

时间:2018-11-30 21:59:35

标签: python

因此,我懒惰的后方正试图在python 3.x中创建一个膳食计划生成器,因此我不必每个星期五花30分钟来弄清楚我应该吃什么,但是我是新手,正在为某些事情而苦苦挣扎。我仍在学习Udemy课程,但是我想弄清楚代码以正确学习。任何人,这是到目前为止我得到的:

class Meals():

    def __init__(self,breakfast,lunch,dinner):
        self.breakfast=breakfast
        self.lunch=lunch
        self.dinner=dinner
    def __str__(self):
        return f"Breakfast will be {self.breakfast}.\nLunch will be        {self.lunch}.\nDinner will be {self.dinner}."
    def cost(self):
        day_meals=[self.breakfast,self.lunch,self.dinner]
        day_cost=0
        for i in day_meals:
            for ingredient in i:
                for key,value in Shop2.items():
                    if key in ingredient:
                        day_cost+=value
        return f"Today will cost £{round(day_cost,2)}."

如果我这样做:

    monday_meals=Meals(random.choice(list(breakfasts.keys())),random.choice(list(lunches.keys())),random.choice(list(dinners.keys())))

然后调用monday_meals.breakfast,然后得到所需的结果,即从“ breakfast”字典中随机选择的键,但是只要我需要: monday_meals.cost() 然后我得到了0英镑,没有显示错误。

作为参考,我的测试词典如下:

breakfasts={"a bowl of Rice Crispies":["cereal_1","milk"],"Weetabix":["cereal_2","milk"],"some Golden Grahams":["cereal_3","milk"],"toast":["bread","butter"],"scrambled eggs":["egg","egg","milk"]}

lunches={"cereal bars":["cereal_bar","cereal_bar"],"a boring ham sandwich":["bread","ham"],"some fruit":["banana","apple"],"salad":"salad_bag"}

dinners={"Student Meal #1":["mince","red_sauce","pepper","onion"],"Student Meal #2":["c_breast","white_sauce","onion","pepper"],"Student Meal #3":["egg","pepper","tomato","onion"]}

Shop2={"egg":0.3,"tomato":0.35,"pepper":0.33,"onion":0.4,"mince":1.2,"c_breast":0.7,"rice":0.8,"red_sauce":1.4,"white_sauce":1.5,"cereal_1":0.4,"milk":0.13,"cereal_2":0.35,"cereal_3":0.45,"bread":0.04,"butter":0.04,"cereal_bar":0.75,"ham":0.25,"banana":0.3,"apple":0.3,"salad":0.75}

如果能找到一种更简便的方法来计算一日三餐的费用,我将不胜感激。

4 个答案:

答案 0 :(得分:1)

您可以通过以下方式实现您的设计:

# inside your class:

@staticmethod
def calculate_meal_cost(ingredients, shopdict):
    return sum(shopdict[ingredient] for ingredient in ingredients)

@property
def cost(self):
    breakfast_cost = self.calculate_meal_cost(breakfasts[self.breakfast], Shop2)
    lunch_cost = self.calculate_meal_cost(lunches[self.lunch], Shop2)
    dinner_cost = self.calculate_meal_cost(dinners[self.dinner], Shop2)
    return breakfast_cost + lunch_cost + dinner_cost

然后:

meal = Meal(...)  # however you pick your meals is fine
meal.cost  # note: no parens

答案 1 :(得分:1)

问题出在实例化类时传递的内容。顾名思义,breakfasts.keys()只是为您提供该字典的键:这些键是冒号左侧的东西,例如“一碗米饭脆皮”。实际的成分是,但是它们永远不会发送到Meals实例。因此,当您遍历“成分”时,实际上是遍历密钥的字母。

您可以通过使用.values()代替那里的.keys()来解决此问题,尽管更好的方法可能是传递键和值,以便您的__str__方法输出描述,而不是配料;我将其保留为练习...

答案 2 :(得分:1)

您的Meals对象正在使用餐的String名称进行初始化(例如,随机选择Breakfasts.keys()可能是“ Weetabix”)。

当您遍历day_meals并执行“ i中的成分”时,实际上您正在遍历Weetabix的每个“字符”,因此您的成分将是“ W”,“ e”,“ e” ..等等。 >

相反,您可能想通过选择breakfasts.items()来初始化Meals。那么你将有一个元组,例如(“ Weetabix”,[“ cereal_2”,“牛奶”]),在self.breakfast中。

然后您可以在循环中解包:

for name,ingredients in day_meals:
   for i in ingredients:
      # and so on..

答案 3 :(得分:0)

创建Meals对象后,必须调用cost方法。目前,您仅创建对象。试试:

monday_meals=Meals(random.choice(list(breakfasts.keys())),random.choice(list(lunches.keys())),random.choice(list(dinners.keys())))
print monday_meals.cost()
print monday_meals