假设我有一个函数foo,它带有一个列表baz,而在foo中我想像这样清除baz:
baz = []
foo(baz)
foo(baz):
baz = []
现在,这段代码没有按照我的意愿去做,因为它创建了一个名为baz的新本地列表。我知道还有其他方法可以做到这一点,但我想知道Python解决了这样的含糊不清的声明
baz = []
可以解释为告诉Python将外部作用域baz变量指向一个新的空白内存块,或者创建一个指向空白内存块的新指针。
修改
请注意,我不是在询问如何清除列表。我问的是Python解释器的行为。请在downvoting之前清楚地阅读这个问题。
答案 0 :(得分:2)
如果您使用global
或nonlocal
关键字明确告知变量,则Python只会将变量赋值视为从外部作用域分配变量。 global
用于全局变量,nonlocal
是闭包变量的Python 3独占关键字:
x = 1
def change_x():
global x
x = 2
def dont_change_x():
# no global
x = 3
change_x()
print(x) # prints 2
dont_change_x()
print(x) # still prints 2
否则,它总是将赋值解释为赋值给局部变量。
答案 1 :(得分:1)
如果您打算清除列表中的项目,则无需将当前名称重新分配给新列表,只需通过切片清除旧名称:
foo(baz):
baz[:] = [] # clears out list baz
baz[:]
是一种索引列表中所有项目并为其指定新值的方法
更新:
如果在新列表的赋值中使用相同的内容,解释器只需将该名称重新分配给新的list
对象:
>>> baz = []
>>> id(baz)
14832064
>>> baz = []
>>> id(baz)
14834304
除非您使用切片重构旧列表,否则名称baz
将不再是old
列表的引用。< / p>
答案 2 :(得分:1)
看一下这篇文章,了解passing parameters by assignment的python方式。
发生的事情是您正在将变量baz重新定义为另一个列表,因此它不再具有对外部baz的引用。您需要直接操作列表中的元素。
例如,如果您要向baz添加元素,外部列表将获得更改:
def foo(baz):
baz.append('baz')
但这样做:
def foo(baz):
baz = []
您为baz分配了一个新列表,现在已经破坏了对外部baz的引用。
在您的情况下,您有2个选项可以清除列表:
del baz[:]
baz[:] = []
答案 3 :(得分:0)
使用切片:
>>> def foo(baz):
... baz[:] = []
...
>>> baz = [1, 2]
>>> foo(baz)
>>> baz
[]
my_list[:]
告诉Python将my_list
中的所有元素替换为赋值语句右侧的内容,引用相同的my_list
对象。
答案 4 :(得分:-1)
如果要清除列表,请使用.clear()
而不是创建新列表:
def foo(baz):
baz.clear()
附注:要访问baz
中的外部foo()
,您可以使用global
关键字。但是在这种情况下不存在歧义,因为python会强制你通过抛出SyntaxError来重命名参数。
def foo(baz2):
global baz
baz = []
请注意,不鼓励使用global
。