P31
- 和 * 都遵循不修改原有的操作对象, 而是创建一个新的序列
>>> a = [1, 2, 3]
>>> c = a * 2
>>> a[0] = 3
>>> c
[1, 2, 3, 1, 2, 3]
如果在 a * n 这个语句中,序列 a 里的元素是对其他可变对象的引用的话,你就需要格外注意了,因为这个式子的结果可能会出乎意料。比如,你想用my_list = [[]] * 3 来初始化一个由列表组成的列表,但是你得到的列表里包含的 3 个元素其实是 3 个引用,而且这 3 个引用指向的都是同一个列表。这可能不是你想要的效果
a = [[''] * 3] * 3
a[0][1] = 1
a
[['', 1, ''], ['', 1, ''], ['', 1, '_']]
P33
可变序列一般都实现了 iadd 方法,因此 += 是就地加法。而不可变序列根
本就不支持这个操作,对这个方法的实现也就无从谈起
str 是一个例外,因为对字符串做 += 实在是太普遍了,所以 CPython 对它做了优化。为 str 初始化内
存的时候,程序会为它留出额外的可扩展空间,因此进行增量操作的时候,并不会涉及复制原有字符
串到新位置这类操作。