将项目添加到列表的副本意外行为
Posted
技术标签:
【中文标题】将项目添加到列表的副本意外行为【英文标题】:Adding an item to a copy of a list unexpected behavior 【发布时间】:2019-11-06 05:37:41 【问题描述】:我给你介绍两个functions
:
class Message:
def __init__(self, text, log):
self.text = text
self.log = log
def copy(self):
return Message(self.text, self.log)
def add(self, more):
self.text += more
self.log += more
return self
msg1 = Message("",[]).add("A")
msg2 = msg1.copy().add("B")
print(msg1.text, msg1.log)
print(msg2.text, msg2.log)
这个prints
A ['A', 'B'] AB ['A', 'B']
这是(对我而言)意想不到的事情发生的地方 -
list_1 = [1]
list_2 = list_1.copy()
list_2 += 'b'
print(list_1) # prints [1]
print(list_2) # prints [1,'b']
所以,我似乎无法理解为什么行为与我在两个函数中使用 += 不同。我已经阅读了object.__iadd__
的文档,但无法真正理解我的问题的解决方案。
【问题讨论】:
【参考方案1】:在第一种情况下,您将相同的对象 ([]
) 传递给 msg1
和 msg2
。当您使用msg1
修改该对象时,msg2
也会看到该更改。
如果您想在msg2
中使用不同的对象,您还需要复制log
:
def copy():
return Message(self.text, self.log.copy())
这就是你在第二种情况下所做的,这就是它起作用的原因。
【讨论】:
感谢您的回复。 msg1.copy() 不会创建一个全新的列表吗?例如,list[:]
允许我调整我复制的任何内容,只要它是一个简单的列表
msg1.copy()
是你的代码。不做任何复制。只是任务。如果你想让 python 创建新对象,你必须告诉它这样做。
很抱歉可能会问同样的问题,但我不太明白。这不是我想要任何事情发生,我只是在测试列表的行为。通过使用msg1.copy()
,我不会以可能是something = self.log[:]
的方式创建列表吗?
您确实意识到msg.copy()
是您 在Message
类中定义的方法。仅仅通过调用方法copy()
不会让它复制任何东西。在您的情况下,您定义的 copy()
方法不会进行任何复制。以上是关于将项目添加到列表的副本意外行为的主要内容,如果未能解决你的问题,请参考以下文章
Power Query:当特定值出现在另一列中时如何将一个添加到列中