使用[:]进行列表赋值

18 投票
6 回答
5796 浏览
提问于 2025-04-17 03:48

这两段代码有什么区别呢?

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 对象的索引。这意味着如果有多个名字指向同一个对象,当你通过任何一个名字去引用它时,你会看到变化,就像你使用 appendextend 或其他类似的操作一样。

下面是一个区别的例子:

>>> 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 切片赋值的内存使用

撰写回答