删除列表的不同方式

gra*_*tle 35 python memory-management list

我想了解原因:

  • a = [];
  • del a; 和
  • del a[:];

表现得如此不同.

我为每个人进行了测试,以说明我目睹的差异:

>>> # Test 1: Reset with a = []
... 
>>> a = [1,2,3]
>>> b = a
>>> a = []
>>> a
[]
>>> b
[1, 2, 3]
>>> 
>>> # Test 2: Reset with del a
... 
>>> a = [1,2,3]
>>> b = a
>>> del a
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
[1, 2, 3]
>>> 
>>> # Test 3: Reset with del a[:]
... 
>>> a = [1,2,3]
>>> b = a
>>> del a[:]
>>> a
[]
>>> b
[]
Run Code Online (Sandbox Code Playgroud)

我确实找到了清除列表的不同方法,但我没有找到行为差异的解释.任何人都可以澄清这个吗?

Mal*_*imi 25

测试1

>>> a = [1,2,3] # set a to point to a list [1, 2, 3]
>>> b = a # set b to what a is currently pointing at
>>> a = [] # now you set a to point to an empty list

# Step 1: A --> [1 2 3]

# Step 2: A --> [1 2 3] <-- B

# Step 3: A --> [     ] [1 2 3] <-- B

# at this point a points to a new empty list
# whereas b points to the original list of a
Run Code Online (Sandbox Code Playgroud)

测试2

>>> a = [1,2,3] # set a to point to a list [1, 2, 3]
>>> b = a # set b to what a is currently pointing at
>>> del a # delete the reference from a to the list

# Step 1: A --> [1 2 3]

# Step 2: A --> [1 2 3] <-- B

# Step 3:       [1 2 3] <-- B

# so a no longer exists because the reference
# was destroyed but b is not affected because
# b still points to the original list
Run Code Online (Sandbox Code Playgroud)

测试3

>>> a = [1,2,3] # set a to point to a list [1, 2, 3]
>>> b = a # set b to what a is currently pointing at
>>> del a[:] # delete the contents of the original

# Step 1: A --> [1 2 3]

# Step 2: A --> [1 2 3] <-- B

# Step 2: A --> [     ] <-- B

# both a and b are empty because they were pointing 
# to the same list whose elements were just removed  
Run Code Online (Sandbox Code Playgroud)


jon*_*rpe 15

在你的三种"删除Python列表的方法"中,只有一个实际上改变了原始列表对象; 另外两个只影响名称.

  1. a = []创建一个新的列表对象,并将其分配给名称a.
  2. del a删除名称,而不是它引用的对象.
  3. del a[:]删除名称引用的列表中的所有引用a(但类似地,它不会直接影响从列表引用的对象).

可能值得阅读这篇关于Python名称和值的文章,以便更好地理解这里发生的事情.

  • @letsc它取决于是否有任何*其他*引用它; `del a`将删除名称并减少它指向的任何引用计数. (3认同)

Pad*_*ham 7

Test 1:重新绑定a到一个新对象,b仍然保存对原始对象的引用,a只是通过重新绑定a到一个新对象的名称不会更改b指向的原始对象.

Test 2:你为名称a所以它不再存在,但你仍然有一个对内存中对象的引用b.

Test 3 a[:]就像复制列表或想要更改列表的所有元素一样,是指对列表中存储的对象的引用而不是名称a.b得到清除也是因为它是对效果a内容的更改的引用.ab

行为记录在案:

有一种方法可以从列表中删除一个项目,而不是它的值:del语句.这与pop() 返回值的方法不同.该del语句还可用于从列表中删除切片或清除整个列表(我们之前通过将空列表分配给切片来执行此操作).例如:

>>>
>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]
Run Code Online (Sandbox Code Playgroud)

del 也可以用来删除整个变量:

>>>
>>> del a
Run Code Online (Sandbox Code Playgroud)

a以下引用名称是一个错误(至少在为其分配另一个值之前).我们稍后会发现其他用途del.

因此,del a实际上只删除a,a = []重新绑定到新对象并 del a[:]清除 a.在你的第二次测试中,如果b没有对象的引用,它将被垃圾收集.


ODi*_*lva 5

del a
Run Code Online (Sandbox Code Playgroud)

a从范围中删除变量.引自python docs:

删除名称将删除该名称与本地或全局名称空间的绑定,具体取决于名称是否出现在同一代码块中的全局语句中.

del a[:]
Run Code Online (Sandbox Code Playgroud)

只是删除了内容a,因为删除被传递给a对象,而不是应用于它.再次来自文档:

删除属性引用,订阅和切片将传递给所涉及的主对象; 删除切片通常等同于分配右类型的空切片(但即使这是由切片对象确定的).

.