python序列对象使用+和*和*=和+=
目录
- python中+和*
- 含有可变元素的容器序列对象不可用*
- 对于上边例子,正确做法是用列表推导式:
- 序列增量赋值 *= 和 +=
python中+和*
python中序列都支持 + 和 * 操作。
- + 拼接两个序列,返回拼接后的序列
- * 将一个序列复制几份,然后拼接
- + 和 * 都不改变原有序列对象。
含有可变元素的容器序列对象不可用*
因为容器序列中保存的是元素的引用,如果直接用 * 复制容器对象再拼接,则会得到几份相同的引用。如下边例子。
对于上边例子,正确做法是用列表推导式:
此时因为容器序列对象['_']中只有一个元素,该元素是字符串,因此元素不可变,故可以用 *
序列增量赋值 *= 和 +=
以+=为例讲解,*=类似。
a += b
- +=背后是调用的特殊方法__iadd__,该方法用于就地加法。如果类中没有实现__iadd__,则调用__add__。
- 如果实现了__iadd__,且a为可变序列,则把b复制一份接到a上,对a进行原地改动。效果等价于a.extend(b)。
- 如果没有实现__iadd__,则a += b等价于a = a + b,会先计算a + b生成一个新的对象,然后赋值给a。此时变量名a已经被关联到了新的对象。
- 如果a为不可变序列,不支持该操作。
- *=对应的特殊方法是__imul__。
- 一般对不可变序列进行重复拼接操作效率很低,因为需要构造新对象,但是str是个例外,因为字符串+=操作太普遍,因此CPython进行了优化,为str对象初始化内存的时候预留了可扩展空间。