2017-03-18 54 views
2

阅读文档:明确蟒蛇德尔如何工作列表和切片

德尔:目标列表的缺失递归删除每一个目标,从 从左到右。

你能澄清一下为什么这段代码能够正常工作吗?

a = [1,2,3] 
c = a[:] 

del c 
print a 
del a[:] 
print a 

此打印:

[1, 2, 3] 

[] 

如果片是指向原始列表的相同元素,那么为什么切片的变量赋值的缺失不作a空的,为什么一个新的列表删除未引用的切片会删除a的元素?

UPD

# -*- coding: utf-8 -*- 

a = [1,2,3] 
c = a[:] 

def list_info(lst): 
    print "list id: {}".format(id(lst)) 
    print "list of item ids:" 
    for item in lst: 
     print "id: {}; value: {}".format(id(item), item) 
    print "" 

list_info(a) 
list_info(c) 
list_info(a[:]) 

打印:

list id: 26945296 
list of item ids: 
id: 23753600; value: 1 
id: 23753588; value: 2 
id: 23753576; value: 3 

list id: 26920560 
list of item ids: 
id: 23753600; value: 1 
id: 23753588; value: 2 
id: 23753576; value: 3 

list id: 26946136 
list of item ids: 
id: 23753600; value: 1 
id: 23753588; value: 2 
id: 23753576; value: 3 

正如你所看到的,所有列表项实际上是相同的对象。

+0

“如果一个切片是新列表”假定事实没有证据。 –

+1

做'id(a)'和'id(c)'...它们是不同的,因为'c = a [:]'会做一个浅拷贝 – Sundeep

+0

所有这些int都是相同的对象; “包含”它们的列表实际上包含*引用*。删除一些这些引用不会影响其他引用。 –

回答

4

这里是你在做什么:

a = [1,2,3] 

创建新的列表对象。指向它的创建名称a

​​

创建列表对象的副本。创建名称c指向它。

del c 

删除名称c。它用来指向的对象现在是垃圾,最终将被收集。这对第一个对象没有影响。

print a 

打印什么a指向第一个对象。

del a[:] 

删除a指向的对象的所有元素。它现在是一个空的列表。

print a 

打印空白列表。

那么,这两行之间有什么区别?

del c 
del a[:] 

第一行从命名空间中删除名称。第二行 从对象中移除元素。

编辑:我明白了,你不清楚他们为什么会这么做。从Python Language Reference, Section 6.5

删除一个名字去掉这个名字从 本地或全局命名空间,这取决于名称是否在同一个代码块 `global`声明发生的结合。如果名称未绑定,则会引发NameError异常。

这就是运行del c时发生的情况。

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

这就是运行del a[:]时发生的情况。

+0

但是[:]会创建一个新列表,但名称空间中没有名称并且对象与原始列表中的对象相同。我在哪里可以读del从命名空间中删除名称,如果它有它的名字,如果没有,它会删除它的子对象? –

+0

我已更新我的问题 –

+0

当您说“删除指向的对象的所有元素”时,可能值得强调的是,它会删除列表中的元素,即引用,而不是对象。是否删除实际对象取决于它们是否在别处引用。 –

0

从DOC:

list.clear()删除列表中的所有项目。相当于del a [:]。

del a[:]等于a.clear()

你可以尝试打印id(a)id(c),它们是不同的对象。