从类创建python3列表创建一个全局列表而不是一系列迭代列表

时间:2017-08-12 22:00:51

标签: python-3.x

所以这就是我遇到的问题。我试图迭代makeAThing类,然后使用makeAList类创建迭代列表。它不是为makeAThing的每次迭代创建单独的列表,而是制作一个大的全局列表并为其添加不同的值。有什么我想念/不知道的,或者这只是python的行为?

class ListMaker(object):    

    def __init__(self,bigList = []):
        self.bigList = bigList



class makeAThing(object):    

    def __init__(self,name = 0, aList = []):
        self.name = name
        self.aList = aList

    def makeAList(self):
        self.aList = ListMaker()




k = []
x = 0
while x < 3:
    k.append(makeAThing())
    k[x].name = x
    k[x].makeAList()
    k[x].aList.bigList.append(x)
    x += 1    

for e in k:
    print(e.name, e.aList.bigList)

output:

0 [0, 1, 2]
1 [0, 1, 2]
2 [0, 1, 2]


the output I am trying to achieve:
0 [0]
1 [1]
2 [2] 

之后我希望能够编辑单个列表并将它们分配给它们的迭代

1 个答案:

答案 0 :(得分:1)

您的init函数正在使用可变的默认参数。

From the Python documentation:

  

默认参数值从左到右进行评估   执行函数定义。这意味着表达式是   在定义函数时评估一次,并且相同   每个呼叫使用“预先计算的”值。这是特别的   当默认参数是可变对象时,重要的是要理解   例如列表或字典:如果函数修改了对象   (例如,通过将项目附加到列表中),默认值有效   改性。这通常不是预期的。解决这个问题的方法   是使用None作为默认值,并在正文中显式测试它   功能,例如:

def whats_on_the_telly(penguin=None):
    if penguin is None:
        penguin = []
    penguin.append("property of the zoo")
    return penguin

在您的代码中,默认参数bigList = []被评估一次 - 当定义函数时 - 创建一个空列表。每次调用该函数时,都会使用相同的列表 - 即使它不再是空的。

默认参数aList = []存在同样的问题,但您通过调用self.aList会立即覆盖makeAList,因此不会导致任何问题。

要使用您的代码验证这一点,请在代码执行后尝试以下操作:

print(k[0].aList.bigList is k[1].aList.bigList)

对象是一样的。

有些情况下这种行为很有用(记住会记住 - 虽然还有其他/更好的方法)。通常,避免使用可变的默认参数。空字符串很好(并经常使用),因为字符串是不可变的。对于列表,字典和排序,您必须在函数内添加一些逻辑。