Python - 使用乘法运算符在列表中创建对象副本

13 投票
3 回答
14040 浏览
提问于 2025-04-15 15:16

在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__ 方法...?-)

撰写回答