Python 文档说切片列表会返回一个新列表。
现在,如果返回“新”列表,我有以下与“分配给切片”相关的问题
a = [1, 2, 3]
a[0:2] = [4, 5]
print a
现在输出将是:
[4, 5, 3]
您混淆了两个使用非常相似语法的不同操作:
1)切片:
b = a[0:2]
这会复制
a
的切片并将其分配给 b
.
2)切片分配:
a[0:2] = b
这个用a
的内容替换
b
的切片。
虽然语法相似(我想是设计出来的!),但这是两种不同的操作。
当您在
a
运算符的左侧指定 =
时,您正在使用 Python 的 normal assignment,它将当前上下文中的名称 a
更改为指向新值。这不会更改 a
指向的先前值。
通过在
a[0:2]
运算符的左侧指定 =
,您告诉 Python 您想要使用 slice assignment。切片赋值是列表的一种特殊语法,您可以在其中插入、删除或替换列表中的内容:
插入:
>>> a = [1, 2, 3]
>>> a[0:0] = [-3, -2, -1, 0]
>>> a
[-3, -2, -1, 0, 1, 2, 3]
删除:
>>> a
[-3, -2, -1, 0, 1, 2, 3]
>>> a[2:4] = []
>>> a
[-3, -2, 1, 2, 3]
替换:
>>> a
[-3, -2, 1, 2, 3]
>>> a[:] = [1, 2, 3]
>>> a
[1, 2, 3]
注:
切片的长度可能与切片的长度不同 分配的序列,从而改变目标序列的长度,如果 目标序列允许它。 - 来源
Slice assignment 提供与 tuple unpacking 类似的功能。例如,
a[0:1] = [4, 5]
等同于:
# Tuple Unpacking
a[0], a[1] = [4, 5]
通过元组拆包,您可以修改非顺序列表:
>>> a
[4, 5, 3]
>>> a[-1], a[0] = [7, 3]
>>> a
[3, 5, 7]
但是,元组拆包仅限于替换,因为您不能插入或删除元素。
在所有这些操作之前和之后,
a
是完全相同的列表。 Python 只是提供了很好的语法糖来就地修改列表。
我之前遇到过同样的问题,它与语言规范有关。根据赋值语句,
__setitem__
。 a[i] = x
等同于 a.__setitem__(i, x)
.如果赋值左边是slice,Python也会调用
__setitem__
,只是参数不同:
a[1:4]=[1,2,3]
相当于
a.__setitem__(slice(1,4,None), [1,2,3])
这就是为什么“=”左侧的列表切片表现不同的原因。
通过在分配操作的左侧切片,您指定要分配给哪些项目。
当您执行
a[0:2] = [4,5]
时,您为=
(切片a[0:2]
)的左侧分配了=
右侧的值,[4,5]
.