Python文档指出切片一个列表会返回一个新的列表。
现在,如果返回一个“新”的列表,那么我对“切片赋值”有以下问题:
a = [1, 2, 3]
a[0:2] = [4, 5]
print a
现在的输出将会是:
[4, 5, 3]
- 返回值的函数怎么可能出现在表达式的左边?
- 是的,我读过文档,它说这是可能的,但既然切片一个列表会返回一个“新”的列表,那为什么原始列表被修改了呢?我无法理解它背后的机制。
Python文档指出切片一个列表会返回一个新的列表。
现在,如果返回一个“新”的列表,那么我对“切片赋值”有以下问题:
a = [1, 2, 3]
a[0:2] = [4, 5]
print a
现在的输出将会是:
[4, 5, 3]
b = a[0:2]
这将复制 a
切片并将其赋值给 b
。
2) 切片赋值:
a[0:2] = b
这将用b
的内容替换a
的切片。
尽管语法相似(我猜是有意为之!),但这是两个不同的操作。
for i in list[1:]:
,但我不想复制任何内存。我该怎么做? - Dubslowstart=1
,stop=None
。这样可以避免任何副本,并使用惰性评估(在你的情况下是对原始列表的惰性访问)。 - Spiros=
操作符的左侧指定 a
时,你使用的是 Python 的 普通赋值,它更改了当前上下文中名称 a
指向的新值。这不会更改 a
原来所指向的值。=
操作符的左侧指定 a[0:2]
时,你告诉 Python 你想使用 切片赋值。切片赋值是一个特殊的列表语法,可以插入、删除或替换列表内容:
插入:>>> 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]
注意:
切片的长度可能与分配的序列的长度不同,因此如果目标序列允许,则会更改目标序列的长度。- 来源
切片赋值提供了类似于元组拆包的功能。例如,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只是提供了一种简洁的语法来原地修改列表。
a[:] = some_list
和 a = some_list[:]
或者 a = some_list
是等价的吗? - jadkik94a[:] = some_list
将 a
的每个元素设置为 some_list
中的元素。执行你提到的任何一种方法都会改变 a
的值。例如:a = [1, 2, 3]
,b = a
,a[:] = [4, 5, 6]
,a is b
。如果它改变了 a
的值而不是突变它,最后一行将为 False。 - Casey Kuballstart: stop: step
的值是否总是应该为正数? - strikerspsa[-5:3] = list(range(8))
似乎会将值列表插入到a[-5]
,而不是替换a[-5:]
和a[:3]
。但是,您可以同时使用负起始和停止以及负步长。 - Casey Kuball我之前也遇到过同样的问题,与语言规范有关。根据赋值语句:
如果赋值操作的左侧是下标,Python会在该对象上调用__setitem__
方法。 a[i] = x
等价于a.__setitem__(i,x)
。
如果赋值操作的左侧是切片,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]
。