将新对象值附加到字典中的每个键值项

Append new object value to each key-value item in a dictionary

我想将新成分添加到列表中,该列表是 Pizza 对象的一部分。此对象保存为 pizzas 中的键值字典的值(请参见下面的代码)。

class Pizza:
    def __init__(self, ingredients = []):
        self.ingredients = ingredients


def main():
    pizzas = {}
    availablePizzas = ["Margherita", "Marinara", "Diavola"]

    for pizza in availablePizzas:
        pizzas.update({pizza: Pizza()})

    pizza = pizzas.get("Margherita")
    pizza.ingredients.append("Mozzarella")
    pizzas.update({"Margherita": pizza})

    printPizzas(pizzas)


def printPizzas(pizzas):
    for pizza, value in pizzas.items():
        print(pizza, value.ingredients)


main()

当我运行此代码时,它会将新成分Mozzarella附加到字典pizzas中的每个披萨。结果:

Margherita ['Mozzarella']
Marinara ['Mozzarella']
Diavola ['Mozzarella']

如何更改此设置,以便仅将成分 Mozzarella 添加到关键成分 Margherita 中?请求结果:

Margherita ['Mozzarella']
Marinara []
Diavola []

问题来自您的 class 定义:

class Pizza:
    def __init__(self, ingredients = []):
        self.ingredients = ingredients

您正在使用可变引用作为 ingredients 默认值的参数。此引用(因此是同一个列表)在您的 class 定义第一次被读取时被初始化,并使用此默认参数为 Pizza 的每个实例共享,因此当您附加一个元素只有其中之一。

您应该改为在方法体内声明默认值:

class Pizza:
    def __init__(self, ingredients = None):
        if ingredients is None:
            self.ingredients = []
        else:
            self.ingredients = ingredients
        
        # Using ternary :
        # self.ingredients = ingredients if ingredients is not None else []

您可以在此处获得更多信息:https://docs.python-guide.org/writing/gotchas/

这很有趣。发生这种情况是因为可变默认参数在 Python 中的工作方式。理想情况下,您应该在此处阅读相关内容:

tl;dr 是 python 函数只创建一次默认参数,所以当你这样做时: def __init__(self, ingredients = []): 只创建一个列表,所有 Pizza().ingredients 将指向这个单个列表。您可以通过此处的答案来避免这种情况:What is the pythonic way to avoid default parameters that are empty lists?

P.S:

    pizza = pizzas.get("Margherita")
    pizza.ingredients.append("Mozzarella")
    pizzas.update({"Margherita": pizza})

这里的pizzas.update什么都不做。 "Margherita" 已经指向并且您已将 Pizza 存储在变量 pizza 中。所以当 Pizza 中的数据改变时,字典仍然指向同一个对象。