小心python的list乘法

小心python的list乘法

转载  2016年11月17日 16:02:05

python是个很方便的语言,我经常使用python*操作符去构建list中的重复元素。例如:

>>> l = [1] * 4
>>> print(l)
>>> [1, 1, 1, 1]

这样做确实很方便,但也很危险,请先看下面的代码:

>>> l = [{'a': 1}] * 4
>>> print(l)
>>> [{'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}]

>>> l[0]['a'] = 2
>>> print(l)
>>> [{'a': 2}, {'a': 2}, {'a': 2}, {'a': 2}]

我改了list中的一个dict的值为2, 全部的dict都为2了!!!

一句话解释就是,*操作符在实现上是复制了值的引用,而不是创建了新的对象。所以上述的list里面,是4个指向同一个dict对象的引用。

*操作符对于不可变对象很安全,但对于可变对象,可能就不是你期望的结果了。因为不可变对象是复制值,而可变对象是复制引用。

使用以下代码避免问题:

>>> l = [{'a': 1} for _ in range(4)]
>>> print(l)
>>> [{'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}]

>>> l[0]['a'] = 2
>>> print(l)
>>> [{'a': 2}, {'a': 1}, {'a': 1}, {'a': 1}]

python是个很方便的语言,我经常使用python*操作符去构建list中的重复元素。例如:

>>> l = [1] * 4
>>> print(l)
>>> [1, 1, 1, 1]

这样做确实很方便,但也很危险,请先看下面的代码:

>>> l = [{'a': 1}] * 4
>>> print(l)
>>> [{'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}]

>>> l[0]['a'] = 2
>>> print(l)
>>> [{'a': 2}, {'a': 2}, {'a': 2}, {'a': 2}]

我改了list中的一个dict的值为2, 全部的dict都为2了!!!

一句话解释就是,*操作符在实现上是复制了值的引用,而不是创建了新的对象。所以上述的list里面,是4个指向同一个dict对象的引用。

*操作符对于不可变对象很安全,但对于可变对象,可能就不是你期望的结果了。因为不可变对象是复制值,而可变对象是复制引用。

使用以下代码避免问题:

>>> l = [{'a': 1} for _ in range(4)]
>>> print(l)
>>> [{'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}]

>>> l[0]['a'] = 2
>>> print(l)
>>> [{'a': 2}, {'a': 1}, {'a': 1}, {'a': 1}]

猜你喜欢

转载自blog.csdn.net/xingce_cs/article/details/79178077