【发布时间】:2012-04-26 17:02:38
【问题描述】:
我在很多地方看到lists 使用切片分配。当与(非默认)索引一起使用时,我能够理解它的用途,但我无法理解它的用途,例如:
a_list[:] = ['foo', 'bar']
这和它有什么不同
a_list = ['foo', 'bar']
?
【问题讨论】:
标签: python list variable-assignment slice
我在很多地方看到lists 使用切片分配。当与(非默认)索引一起使用时,我能够理解它的用途,但我无法理解它的用途,例如:
a_list[:] = ['foo', 'bar']
这和它有什么不同
a_list = ['foo', 'bar']
?
【问题讨论】:
标签: python list variable-assignment slice
a_list = ['foo', 'bar']
在内存中创建一个新的list 并将名称a_list 指向它。 a_list之前所指的无关紧要。
a_list[:] = ['foo', 'bar']
调用a_list 对象的__setitem__ 方法,以slice 作为索引,在内存中创建一个新的list 作为值。
__setitem__ 评估slice 以找出它代表的索引,并在它传递的值上调用iter。然后它遍历对象,将slice 指定范围内的每个索引设置为对象的下一个值。对于lists,如果slice 指定的范围与可迭代的长度不同,则调整list 的大小。这使您可以做许多有趣的事情,例如删除列表的各个部分:
a_list[:] = [] # deletes all the items in the list, equivalent to 'del a_list[:]'
或在列表中间插入新值:
a_list[1:1] = [1, 2, 3] # inserts the new values at index 1 in the list
但是,对于“扩展切片”,step 不是一个,迭代必须是正确的长度:
>>> lst = [1, 2, 3]
>>> lst[::2] = []
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
ValueError: attempt to assign sequence of size 0 to extended slice of size 2
将切片分配给a_list 的主要不同之处在于:
a_list 必须已经指向一个对象a_list 指向新对象slice 索引的__setitem__
【讨论】:
差别很大!在
a_list[:] = ['foo', 'bar']
您修改了绑定到名称 a_list 的现有列表。另一方面,
a_list = ['foo', 'bar']
为名称a_list分配一个新列表。
也许这会有所帮助:
a = a_list = ['foo', 'bar'] # another name for the same list
a_list = ['x', 'y'] # reassigns the name a_list
print a # still the original list
a = a_list = ['foo', 'bar']
a_list[:] = ['x', 'y'] # changes the existing list bound to a
print a # a changed too since you changed the object
【讨论】:
通过分配给a_list[:],a_list 仍然引用相同的列表对象,但内容已修改。通过分配给a_list,a_list 现在引用一个新的列表对象。
查看它的id:
>>> a_list = []
>>> id(a_list)
32092040
>>> a_list[:] = ['foo', 'bar']
>>> id(a_list)
32092040
>>> a_list = ['foo', 'bar']
>>> id(a_list)
35465096
如您所见,它的id 不会随切片分配版本而改变。
两者之间的差异可能会导致完全不同的结果,例如,当列表是函数的参数时:
def foo(a_list):
a_list[:] = ['foo', 'bar']
a = ['original']
foo(a)
print(a)
这样,a 也被修改了,但如果使用 a_list = ['foo', 'bar'] 代替,a 保持其原始值。
【讨论】:
a_list = ['foo', 'bar']
a=a_list[:] # by this you get an exact copy of a_list
print(a)
a=[1,2,3] # even if you modify a it will not affect a_list
print(a)
print(a_list)
【讨论】:
['foo', 'bar'] 分配给a_list[:]。