【问题标题】:Shallow copy list of objects对象的浅拷贝列表
【发布时间】:2017-06-28 20:17:26
【问题描述】:

将对象的引用从一个列表转移到另一个列表的最佳方法是什么(将对象从一个列表移动到另一个列表)。为了清楚起见,我需要在复制后从d[1] 中删除对象

class MyObject:
    def __init__(self,v):
        self.value = v

d = {1: [MyObject("obj1"),MyObject("obj2")], 2: []}

#which one?
#d[2] = [obj for obj in d[1]]

#d[2] = d[1][:]

#d[2] = d[1].copy()

#clear d[1]
#d[1] = []

for i in range(len(d[1])):
    d[2].append(d[1].pop(0))

for o in d[2]:
    print (o.value)

【问题讨论】:

  • "best" 究竟如何?它是否对先前的列表具有破坏性是否重要(您的一些建议是,有些不是)。为什么不直接选择一个,然后把时间花在其他更有用的事情上?
  • 哪个“人”?为什么不问他们他们更喜欢哪一个呢?或者一旦你们有更实用的东西一起使用Code Review
  • 你当然需要提供context。要决定哪个更好,您需要指定 criteria,否则它只是一个意见。如果只是“[随机 SO 用户] 更喜欢哪一个”,那么除了他们谁还能说呢?

标签: python list python-3.x class


【解决方案1】:

哪种方法最好取决于周围代码的细节。是否有任何其他变量或数据结构包含对您的任何一个列表的引用?如果没有,您可以重新绑定字典中的引用(这需要O(1) 时间,因为没有发生复制):

d = {1: [MyObject("obj1"),MyObject("obj2")], 2: []}
d[2] = d[1]
d[1] = []

如果可能存在对现有列表的其他引用,并且您希望它们继续引用正确的值(例如,对 d[1] 的旧引用在更改后仍应引用 d[1]),那么您想做一个切片分配后跟一个明确的(这是O(N)):

d[2][:] = d[1] # copy data
d[1].clear()

我认为没有充分的理由使用任何其他方法,除非您有一些其他逻辑要应用(例如,如果您只想复制一些值而不是其他值)。

【讨论】:

    【解决方案2】:

    添加字典会掩盖用例。根据您的示例,不清楚您是想要对象的副本还是引用相同对象的列表。

    假设是后者,考虑简化的情况。这真的就像将列表分配给另一个变量一样简单:

    >>> class MyObject(object):
    ...     def __init__(self, v):
    ...         self.value = v
    ...
    >>> x = [MyObject(1), MyObject(2)]
    >>> y = x
    >>> x[1].value
    2
    

    现在,xy 都是相同引用对象的列表。如果我更改一个列表中的对象,它将在另一个列表中更改:

    >>> y[1].value = 3
    >>> x[1].value
    3
    

    在您的用例(带有列表值的字典)中,这非常简单:

    d[2] = d[1]
    

    然后您可以根据需要删除1 键:

    del d[1]
    

    瞧!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-25
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      • 2021-04-20
      • 2012-04-12
      • 2015-08-28
      相关资源
      最近更新 更多