之间有什么区别
list = range(100)
和
list[:] = range(100)
在Python中?
修改
我应该已经提到过,在该分配列表变量已经分配给列表之前:
list = [1, 2, 3]
list = range(100)
或
list = [1, 2, 3]
list[:] = range(100)
答案 0 :(得分:34)
当你这样做时
lst = anything
您将名称 lst
指向对象。它不会更改用于指向任何方式的旧对象lst
,但如果没有其他任何指向该对象的引用计数将降至零并且它将被删除。 / p>
当你这样做时
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 Slice Assignment Memory Usage。
答案 1 :(得分:4)
第一个重新定义内置名称list
以指向某个列表。
第二个因TypeError: 'type' object does not support item assignment
而失败。
答案 2 :(得分:2)
list[:]
指定列表中的范围,在这种情况下,它定义列表的完整范围,即整个列表并更改它们。另一方面,list=range(100)
会消除list
的原始内容并设置新内容。
但请尝试以下方法:
a=[1,2,3,4]
a[0:2]=[5,6]
a # prints [5,6,3,4]
你看,我们用赋值改变了前两个元素。这意味着,使用此表示法,您可以更改列表中的多个元素。
答案 3 :(得分:2)
list[:]
仅在已存在允许切片分配的名为list
的对象时才有效。
此外,您不应将变量命名为list
,因为内置了一个名为list
的{{1}}类型。
答案 4 :(得分:2)
[:]对于制作列表的深层副本也很有用。
def x(l):
f=l[:]
g=l
l.append(8)
print "l", l
print "g", g
print "f", f
l = range(3)
print l
#[0, 1, 2]
x(l)
#l [0, 1, 2, 8]
#g [0, 1, 2, 8]
#f [0, 1, 2]
print l
#[0, 1, 2, 8]
对l的修改反映在g中(因为,两者都指向同一个列表,实际上,g和l都只是python中的名称),而不是f(因为,它是l的副本)
但是,在你的情况下,它没有任何区别。 (虽然,我没有资格评论两种方法的任何内存使用情况。)
编辑
h = range(3)
id(h) #141312204
h[:]=range(3)
id(h) #141312204
h=range(3)
id(h) #141312588
list [:] = range(100)更新列表 list = range(100)创建新列表。
@agf:谢谢你指出我的错误
答案 5 :(得分:1)
list[:] = range(100)
不会对未初始化的变量起作用,因为它正在修改它。 [:]
指定整个列表/ touple。