使用[:]进行列表赋值
这两段代码有什么区别呢?
lst = range(100)
和
lst[:] = range(100)
在进行这个赋值之前,lst
变量已经被赋值为一个列表了:
lst = [1, 2, 3]
lst = range(100)
或者
lst = [1, 2, 3]
lst[:] = range(100)
6 个回答
3
list[:]
这个写法只有在已经有一个叫 list
的对象,并且这个对象支持切片赋值的时候才能用。
另外,你不应该把变量命名为 list
,因为有一个内置的名称也是 list
,它代表的就是列表这种类型。
3
第一个是把内置的名字 list
重新定义成指向某个列表。
第二个会出错,错误信息是 TypeError: 'type' object does not support item assignment
,意思是说你不能给某种类型的对象直接赋值。
41
当你执行
lst = anything
时,你是在把名字 lst 指向一个对象。这样做并不会改变 lst
原来指向的那个对象。如果没有其他东西再指向这个对象,它的引用计数会降到零,然后就会被删除。
而当你执行
lst[:] = whatever
时,你是在遍历 whatever
,创建一个临时的元组,并把元组里的每个项目分配给已经存在的 lst 对象的索引。这意味着如果有多个名字指向同一个对象,当你通过任何一个名字去引用它时,你会看到变化,就像你使用 append
、extend
或其他类似的操作一样。
下面是一个区别的例子:
>>> lst = range(1, 4)
>>> id(lst)
74339392
>>> lst = [1, 2, 3]
>>> id(lst) # different; you pointed lst at a new object
73087936
>>> lst[:] = range(1, 4)
>>> id(lst) # the same, you iterated over the list returned by range
73087936
>>> lst = xrange(1, 4)
>>> lst
xrange(1, 4) # not a list, an xrange object
>>> id(lst) # and different
73955976
>>> lst = [1, 2, 3]
>>> id(lst) # again different
73105320
>>> lst[:] = xrange(1, 4) # this gets read temporarily into a tuple
>>> id(lst) # the same, because you iterated over the xrange
73105320
>>> lst # and still a list
[1, 2, 3]
在速度方面,切片赋值会比较慢。想了解更多关于它的内存使用情况,可以查看 Python 切片赋值的内存使用。