删除列表的不同方法
Different ways of deleting lists
我想了解原因:
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
[]
我确实找到了 Different ways of clearing lists,但我没有找到对行为差异的解释。谁能澄清一下?
Test 1:
将 a
重新绑定到新对象,b
仍然持有对原始对象的 引用 ,a
只是通过将 a
重新绑定到新对象的名称不会更改 b
指向的原始对象。
Test 2:
你删除了名称 a
所以它不再存在但是你仍然有一个对内存中对象的引用 b
.
Test 3
a[:]
就像当您复制列表或想要更改列表的所有元素时,指的是对存储在列表中的对象的引用而不是名称 a
. b
也被清除,因为它是对 a
的引用,因此对 a
内容的更改将影响 b
.
行为是 documented:
There is a way to remove an item from a list given its index instead
of its value: the del
statement. This differs from the pop()
method which returns a value. The del
statement can also be used to
remove slices from a list or clear the entire list (which we did
earlier by assignment of an empty list to the slice). For example:
>>>
>>> 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
[]
del
can also be used to delete entire variables:
>>>
>>> del a
Referencing the name a
hereafter is an error (at least until another
value is assigned to it). We'll find other uses for del
later.
所以只有 del a
实际删除 a
,a = []
将 a 重新绑定到新对象,del a[:]
清除 a
。在你的第二个测试中,如果 b
没有保存对对象的引用,它将被垃圾收集。
del a
正在从范围中删除变量 a
。引用自 python docs:
Deletion of a name removes the binding of that name from the local or
global namespace, depending on whether the name occurs in a global
statement in the same code block.
del a[:]
只是删除 a
的内容,因为删除是传递给 a
对象,而不是应用于它。再次来自文档:
Deletion of attribute references, subscriptions and slicings is passed
to the primary object involved; deletion of a slicing is in general
equivalent to assignment of an empty slice of the right type (but even
this is determined by the sliced object).
。
测试 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
测试 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
测试 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
在你的三个 "ways of deleting Python lists" 中,只有一个 实际上改变了原始列表对象;另外两个只影响名字。
a = []
创建一个 新列表对象 ,并将其分配给名称 a
.
del a
删除名称,不是它所指的对象。
del a[:]
从名称 a
引用的列表中删除 所有引用 (尽管类似地,它不直接影响被引用的对象从列表中引用)。
可能值得阅读 this article 关于 Python 名称和值的内容,以便更好地理解这里发生的事情。
在这三种方法中,只有第三种方法实际导致删除 'a' 指向的列表。让我们快速概览一下。
当您右 a = [1, 2, 3]
时,它会在内存中创建一个列表,其中包含项目 [1, 2, 3],然后让 'a' 指向它。当你写 b = a
时,这预制了所谓的 'shallow copy,' 即它使 'b' 指向与 'a.' 相同的内存块,深度复制将涉及复制内容list 到一个新的内存块,然后指向那个。
现在,当您编写 a = []
时,您正在创建一个没有任何项目的新列表,并让 'a' 指向它。原始列表仍然存在,'b' 指向它。
在第二种情况下,del a
删除指向 [1,2,3] 的指针,而不是数组本身。这意味着 b
仍然可以指向它。
最后,del a[:]
遍历 'a' 指向的数据并清空其中的内容。 'a' 仍然存在,所以你可以使用它。 'b' 也存在,但它指向相同的空列表 'a',这就是为什么它给出相同的输出。
要了解不同删除列表方式的区别,让我们借助图片一一了解。
>>> a1 = [1,2,3]
一个新的列表对象被创建并分配给 a1
。
>>> a2 = a1
我们将 a1
分配给 a2
。因此,list a2
现在指向 a1
指向的列表对象。
下面解释的不同方法:
方法一使用[]
:
>>> a1 = []
将空列表分配给 a1
时,对 a2
没有影响。 a2
仍然引用同一个列表对象,但 a1
现在引用一个空列表。
方法 2 使用 del [:]
>>> del a1[:]
这将删除 a1
指向的列表对象的所有内容。 a1
现在指向一个空列表。由于 a2
也引用了同一个列表对象,它也变成了一个空列表。
方法 3 使用 del a1
>>> del a1
>>> a1
NameError: name 'a1' is not defined
这将从范围中删除变量 a1
。在这里,只是删除了变量 a1
,原始列表仍然存在于内存中。 a2
仍然指向 a1
曾经指向的原始列表。如果我们现在尝试访问 a1
,我们将得到 NameError
.
我想了解原因:
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
[]
我确实找到了 Different ways of clearing lists,但我没有找到对行为差异的解释。谁能澄清一下?
Test 1:
将 a
重新绑定到新对象,b
仍然持有对原始对象的 引用 ,a
只是通过将 a
重新绑定到新对象的名称不会更改 b
指向的原始对象。
Test 2:
你删除了名称 a
所以它不再存在但是你仍然有一个对内存中对象的引用 b
.
Test 3
a[:]
就像当您复制列表或想要更改列表的所有元素时,指的是对存储在列表中的对象的引用而不是名称 a
. b
也被清除,因为它是对 a
的引用,因此对 a
内容的更改将影响 b
.
行为是 documented:
There is a way to remove an item from a list given its index instead of its value: the
del
statement. This differs from thepop()
method which returns a value. Thedel
statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:>>> >>> 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 []
del
can also be used to delete entire variables:>>> >>> del a
Referencing the name
a
hereafter is an error (at least until another value is assigned to it). We'll find other uses fordel
later.
所以只有 del a
实际删除 a
,a = []
将 a 重新绑定到新对象,del a[:]
清除 a
。在你的第二个测试中,如果 b
没有保存对对象的引用,它将被垃圾收集。
del a
正在从范围中删除变量 a
。引用自 python docs:
Deletion of a name removes the binding of that name from the local or global namespace, depending on whether the name occurs in a global statement in the same code block.
del a[:]
只是删除 a
的内容,因为删除是传递给 a
对象,而不是应用于它。再次来自文档:
Deletion of attribute references, subscriptions and slicings is passed to the primary object involved; deletion of a slicing is in general equivalent to assignment of an empty slice of the right type (but even this is determined by the sliced object).
。
测试 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
测试 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
测试 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
在你的三个 "ways of deleting Python lists" 中,只有一个 实际上改变了原始列表对象;另外两个只影响名字。
a = []
创建一个 新列表对象 ,并将其分配给名称a
.del a
删除名称,不是它所指的对象。del a[:]
从名称a
引用的列表中删除 所有引用 (尽管类似地,它不直接影响被引用的对象从列表中引用)。
可能值得阅读 this article 关于 Python 名称和值的内容,以便更好地理解这里发生的事情。
在这三种方法中,只有第三种方法实际导致删除 'a' 指向的列表。让我们快速概览一下。
当您右 a = [1, 2, 3]
时,它会在内存中创建一个列表,其中包含项目 [1, 2, 3],然后让 'a' 指向它。当你写 b = a
时,这预制了所谓的 'shallow copy,' 即它使 'b' 指向与 'a.' 相同的内存块,深度复制将涉及复制内容list 到一个新的内存块,然后指向那个。
现在,当您编写 a = []
时,您正在创建一个没有任何项目的新列表,并让 'a' 指向它。原始列表仍然存在,'b' 指向它。
在第二种情况下,del a
删除指向 [1,2,3] 的指针,而不是数组本身。这意味着 b
仍然可以指向它。
最后,del a[:]
遍历 'a' 指向的数据并清空其中的内容。 'a' 仍然存在,所以你可以使用它。 'b' 也存在,但它指向相同的空列表 'a',这就是为什么它给出相同的输出。
要了解不同删除列表方式的区别,让我们借助图片一一了解。
>>> a1 = [1,2,3]
一个新的列表对象被创建并分配给 a1
。
>>> a2 = a1
我们将 a1
分配给 a2
。因此,list a2
现在指向 a1
指向的列表对象。
下面解释的不同方法:
方法一使用[]
:
>>> a1 = []
将空列表分配给 a1
时,对 a2
没有影响。 a2
仍然引用同一个列表对象,但 a1
现在引用一个空列表。
方法 2 使用 del [:]
>>> del a1[:]
这将删除 a1
指向的列表对象的所有内容。 a1
现在指向一个空列表。由于 a2
也引用了同一个列表对象,它也变成了一个空列表。
方法 3 使用 del a1
>>> del a1
>>> a1
NameError: name 'a1' is not defined
这将从范围中删除变量 a1
。在这里,只是删除了变量 a1
,原始列表仍然存在于内存中。 a2
仍然指向 a1
曾经指向的原始列表。如果我们现在尝试访问 a1
,我们将得到 NameError
.