函数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可以编辑?
答案 0 :(得分:7)
bar = []
重新绑定 bar
;它会创建一个全新的空list
,并将名称bar
绑定到它。 bar
之前是什么都没有关系;它可能是int
,tuple
或dict
,现在已经不相关了,因为它现在已绑定到全新的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()