Python 删除列表的不同方式

Python 删除列表的不同方式,python,list,memory-management,Python,List,Memory Management,我想了解为什么: a=[] dela;及 dela[:] 表现得如此不同 我对每个人都进行了测试,以说明我看到的差异: >>> # Test 1: Reset with a = [] ... >>> a = [1,2,3] >>> b = a >>> a = [] >>> a [] >>> b [1, 2, 3] >>> >>> # Test 2

我想了解为什么:

  • a=[]
  • dela
    ;及
  • dela[:]
表现得如此不同

我对每个人都进行了测试,以说明我看到的差异:

>>> # 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
[]
测试1:用a=[]重置 ... >>>a=[1,2,3] >>>b=a >>>a=[] >>>a [] >>>b [1, 2, 3] >>> >>>#测试2:使用del a重置 ... >>>a=[1,2,3] >>>b=a >>>德拉 >>>a 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 NameError:未定义名称“a” >>>b [1, 2, 3] >>> >>>#测试3:用del a重置[:] ... >>>a=[1,2,3] >>>b=a >>>dela[:] >>>a [] >>>b []
我确实找到了,但我没有找到行为差异的解释。有人能澄清这一点吗?

测试1:
a
重新绑定到一个新对象,
b
仍然保留对原始对象的引用,
a
只是一个名称,通过将
a
重新绑定到一个新对象不会改变
b
指向的原始对象

测试2:
删除名称
a
,使其不再存在,但仍然使用
b
在内存中引用对象

test3
a[:]
就像复制列表或要更改列表的所有元素时一样,列表中的所有元素都引用存储在列表中的对象,而不是名称
a
<代码>b也会被清除,因为它是对
a
的引用,因此对
a
内容的更改将影响
b

这种行为是:

有一种方法可以从给定索引的列表中删除项 它的值: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
[]
del
也可用于删除整个变量:

>>>
>>> del a
在下文中引用名称
a
是一个错误(至少直到另一个 已为其指定值)。稍后我们将找到del的其他用法

因此,只有
dela
实际删除
a
a=[]
将a重新绑定到新对象,并且
dela[:]
清除
a
。在第二个测试中,如果
b
没有保存对该对象的引用,它将被垃圾收集

del a
正在从范围中删除变量
a
。引述自:

删除一个名称将从本地或本地数据库中删除该名称的绑定 全局命名空间,具体取决于名称是否出现在全局命名空间中 语句位于同一代码块中

只需删除
a
的内容,因为删除将传递给
a
对象,而不是应用于该对象。再次从文档中:

传递属性引用、订阅和slicing的删除 涉及的主要对象;通常情况下,需要删除切片 相当于分配正确类型的空片(但偶数) 这由切片对象确定)

测试1
>a=[1,2,3]#将a设置为指向列表[1,2,3]
>>>b=a#将b设置为a当前指向的对象
>>>a=[]#现在将a设置为指向空列表
#步骤1:A-->[1 2 3]
#步骤2:A-->[1,2,3][[1,2,3]>>A=[1,2,3]#将A设置为指向列表[1,2,3]
>>>b=a#将b设置为a当前指向的对象
>>>dela#删除列表中a的引用
#步骤1:A-->[1 2 3]
#步骤2:A-->[1,2,3]>A=[1,2,3]#将A设置为指向列表[1,2,3]
>>>b=a#将b设置为a当前指向的对象
>>>删除a[:]#删除原件的内容
#步骤1:A-->[1 2 3]
#第2步:在三种“删除Python列表的方法”中,只有一种方法实际更改了原始列表对象;另外两个只影响名称

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

  • 阅读Python名称和值可能有助于更好地理解这里发生的事情。

    在这三种方法中,只有第三种方法会删除“a”指向的列表。让我们做一个快速概述

    当您右击
    a=[1,2,3]
    时,它会在内存中创建一个包含项[1,2,3]的列表,然后让“a”指向它。当您写入
    b=a
    时,这将执行所谓的“浅拷贝”,即使“b”指向与“a”相同的内存块。深拷贝将涉及将列表内容复制到新内存块中,然后指向该内存块

    现在,当您编写
    a=[]
    时,您正在创建一个没有项目的新列表,并让“a”指向它。原始列表仍然存在,“b”指向它

    在第二种情况下,
    dela
    删除指向[1,2,3]的指针,而不是它自身的数组。这意味着
    b
    仍然可以指向它


    最后,
    dela[:]
    遍历“a”指向的数据并清空其内容“仍然存在,所以您可以使用它。”b'也存在,但它指向相同的空列表'a',这就是为什么它给出相同的输出。

    要了解不同删除列表方法之间的差异,让我们借助图像逐一查看它们

    >>> a1 = [1,2,3]
    
    将创建一个新的列表对象并将其分配给
    a1

    >>> a2 = a1
    

    我们将
    a1
    分配给
    a2
    。因此,list
    a2
    现在指向
    a1
    指向的列表对象

    >>> 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
    
    >>> 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  
    
    >>> a1 = [1,2,3]
    
    >>> a2 = a1
    
    >>> a1 = []
    
    >>> del a1[:]
    
    >>> del a1
    >>> a1
    NameError: name 'a1' is not defined