切片整个列表和直接赋值的切片分配有什么区别?

时间:2012-04-14 17:57:44

标签: python list variable-assignment slice

我在很多地方都看到了list的切片分配的使用。我可以理解它与(非默认)索引一起使用时的用法,但我无法理解它的用法如下:

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

有什么不同
a_list = ['foo', 'bar']

4 个答案:

答案 0 :(得分:26)

a_list = ['foo', 'bar']

在内存中创建一个新的list,并将名称a_list指向它。与a_list之前指出的内容无关。

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

使用__setitem__作为索引调用a_list对象的slice方法,并在内存中创建新的list作为值。

__setitem__评估slice以确定它代表的索引,并对传递的值调用iter。然后迭代对象,将每个索引设置在slice指定的范围内,并将其设置为对象的下一个值。对于list s,如果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__索引
  4. 支持slice
  5. 右侧的对象必须支持迭代
  6. 没有名称指向右侧的对象。如果没有对它的其他引用(例如,当它是你的例子中的文字时),迭代完成后它将被引用计数不存在。

答案 1 :(得分:12)

差别很大!在

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

答案 2 :(得分:2)

通过分配给a_lista_list仍引用同一个列表对象,并修改内容。通过分配给a_listid现在引用一个新的列表对象。

查看其>>> 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']也会被修改,但如果使用aviewDidLayoutSubviews 仍然是原始值。

答案 3 :(得分: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)