Python - 使用乘法运算符在列表中创建对象副本
在Python中,如果我把一个对象的列表乘以一个整数,我得到的只是对那个对象的引用列表,比如:
>>> a = [[]] * 3
>>> a
[[], [], []]
>>> a[0].append(1)
>>> a
[[1], [1], [1]]
如果我想要的行为是创建一个原始对象的副本列表(比如用“copy.copy()”方法创建的副本,或者其他标准方法),有没有什么优雅的方式可以用同样的乘法运算符来实现呢?还是说我应该直接使用列表推导式或者其他方法?比如:
[[] for x in range(0,3)]
任何版本的Python都可以。
3 个回答
2
列表推导式是实现这个功能的最佳方法。如果你定义一个新类并重载*这个运算符,下一位阅读代码的人会感到非常困惑。
19
这是一个很好的列表推导用法——在我看来,这也是最容易理解的方式。
所以你提到的 [[] for x in range(0,3)]
不是乘法运算符,但它能得到你想要的结果。
4
在一个序列上使用乘法运算符,其实是让里面的东西重复,而不是创建这些东西的副本(无论是浅拷贝还是深拷贝)。你可以随意使用这个运算符,比如:
import copy
class Crazy(object):
def __init__(self, body, weird=copy.copy):
self.gomez = body
self.cousinitt = weird
def __mul__(self, n):
return [self.cousinitt(x) for x in (self.gomez * n)]
a = Crazy([[]]) * 3
...当然,前提是你还保持理智和常识。如果你在想,为什么会觉得乘法运算符 *
可以有完全不同的意思,那可能是因为你在用一些奇怪的方式重新定义了一个类,重载了 __mul__
方法...?-)