25

我在很多地方看到对lists 使用切片分配。当与(非默认)索引一起使用时,我能够理解它的用途,但我无法理解它的用途,例如:

a_list[:] = ['foo', 'bar']

这和有什么区别

a_list = ['foo', 'bar']

?

4

4 回答 4

33
a_list = ['foo', 'bar']

list在内存中创建一个新的并将名称指向a_list它。前面所指的无关紧要a_list

a_list[:] = ['foo', 'bar']

以 a为索引调用对象的__setitem__方法,以在内存中创建的 a 为值。a_listslicelist

__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

  1. a_list必须已经指向一个对象
  2. 该对象被修改,而不是指向a_list一个新对象
  3. 该对象必须__setitem__支持slice索引
  4. 右边的对象必须支持迭代
  5. 没有名称指向右侧的对象。如果没有其他对它的引用(例如当它是您的示例中的文字时),它将在迭代完成后被计数为不存在。
于 2012-04-14T18:02:33.183 回答
14

差别相当大!在

a_list[:] = ['foo', 'bar']

您修改了绑定到 name 的现有列表a_list。另一方面,

a_list = ['foo', 'bar']

为 name 分配一个新列表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
于 2012-04-14T18:04:32.833 回答
3

通过分配给a_list[:]a_list仍然引用相同的列表对象,并修改了内容。通过分配给a_lista_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保持其原始值。

于 2015-08-09T07:33:03.067 回答
0
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)
于 2019-07-22T07:19:36.823 回答