list.clear()与list = []有何不同?

时间:2018-06-30 17:12:21

标签: python python-3.x

函数conv2 = torch.nn.Conv2d(1, 18, kernel_size=3, stride=1, padding=1) 的预期目标是将作为参数提供的数字添加到列表中,如果该数字为0,则重置列表。首先,我写了这个程序:

foo

输出:

def foo(n, bar = []):
    if n == 0:
        bar = []
        print("list empty")
    else:
        bar.append(n)
        for y in bar:
            print(y, end=', ')
        print()

foo(5)
foo(3)
foo(0)
foo(6)

,但似乎5, 5, 3, list empty 5, 3, 6, 被忽略了。然后我用bar = []更改了bar = [],它按我的想法工作:

bar.clear()

输出:

def foo(n, bar = []):
    if n == 0:
        bar.clear()
        print("list empty")
    else:
        bar.append(n)
        for y in bar:
            print(y, end=', ')
        print()

foo(5)
foo(3)
foo(0)
foo(6)

我不明白为什么5, 5, 3, list empty 6, bar.clear()的工作方式不同,因为bar = []应该

  

从集合中删除所有元素。

clear()也是如此。

编辑:我不认为我的问题与“Least Astonishment” and the Mutable Default Argument重复,我知道

  

默认值仅计算一次。

(来自官方教程)但是我要问的是,为什么bar = []不编辑(在这种情况下是清除)列表,而append和clear可以编辑?

6 个答案:

答案 0 :(得分:7)

bar = [] 重新绑定 bar;它会创建一个全新的空list,并将名称bar绑定到它。 bar之前是什么都没有关系;它可能是inttupledict,现在已经不相关了,因为它现在已绑定到全新的list。旧的绑定不再存在于当前方法调用中,而是原来的list remains in existence as the value of the default argument to foo(注意:由于这种混乱,可变默认值被认为是令人惊讶且难看的)。

bar.clear()现有 list上调用一个方法,该方法告诉list清除自身(并且对bar无效)指的;最好是使用clear方法来实现 something ,但除此之外,实际上并不需要它是list)。由于是您开始使用的相同 bar(引用函数默认值中缓存的相同可变默认值),因此会影响您以后的调用(因为bar继续引用list是您提供的可变默认设置。

答案 1 :(得分:3)

您的代码bar是对内存中某些列表的引用。 使用bar = []时,变量bar会与一个新的(空)列表相关联。使用bar.clear()时,您将修改当前列表。

一般来说,这意味着Python中的列表是通过引用而不是通过值传递的。您可以详细了解here

答案 2 :(得分:3)

当您执行list.clear()时,列表将被清除:-) 当您执行list = []时,列表将被新的空列表覆盖。

区别在于,如果某项内容在被覆盖之前就已引用该列表,那么它仍将引用您认为现在已清除的值。

这是引入极其难以调试的bug的绝佳方法。

答案 3 :(得分:3)

您应该真正了解的是变量如何在Python中工作。

变量始终只是对实际内容的引用。变量本身没有存储任何内容,它仅指向未命名的内容。

现在,当您调用foo()时,您所拥有的是内存中的列表,而本地bar指向该列表。如果您呼叫bar.clear(),该列表实际上将被清除,这就是您想要的。但是,如果您说bar = []只是将本地bar绑定到一个新的空列表,而另一个列表(已经包含5和3)保持不变,它将在您下次使用时使用致电foo()

答案 4 :(得分:3)

假设您有一个包含一些值的列表,并将其分配给名为foo的变量。

foo = [0, 1]

此变量现在指向内存中的此列表。

假设您然后创建一个名为bar的新变量并分配给foo。

bar = foo

这两个变量现在指向内存中的同一列表对象。如果然后更改foo并将其等于[],bar会怎样?

foo = []
bar == [0, 1] # True

现在让我们对foo.clear()进行同样的操作。

foo.clear()
bar == [] # True

这是因为在列表上使用clear方法会清除该列表对象,这会影响引用该对象的所有内容,而将变量分配给空列表只会更改该变量的内容,而不会更改任何原始列表。

答案 5 :(得分:1)

这具有所需的属性:

def foo(n, bar = []):

    if n == 0:
        bar[:] = []
        print("list empty")
    else:
        bar.append(n)
        for y in bar:
            print(y, end=', ')
        print()