python 中两个名称指向同一个对象
Two names points to the same object in python
考虑以下示例:
class Test:
def __init__(self, lis: list):
self.list = lis
lis = [1, 2, 3]
obj1 = Test(lis)
obj2 = Test(lis)
print(obj1 is obj2)
print(obj1.list is obj2.list)
obj1.list.reverse()
print(obj2.list)
输出:
False
True
[3, 2, 1]
解释:
我创建了2个相同的对象class,每个对象的“列表”是[1, 2, 3]
。测试名称 obj1
、obj2
是否引用同一个对象,答案是否定的 (False)。但是当我测试 obj1.list is obj2.list
时,当我反转名称 obj1
的列表时,我们得到 'True
' 作为 answer.Thus,该列表也反转了名称 obj2
,因为它是两个名称的相同列表。
我需要一种方法来反转 obj1
的列表,而不是 obj2
。所以我需要创建一个新列表。
最后会是这样的结果:
obj1.list.reverse()
print(obj2.list)
预期输出:
[1, 2, 3]
您正在 self.list
中存储对列表的相同引用,您可以通过复制来避免这种情况:
class Test:
def __init__(self, lis: list):
self.list = <b>lis[:]</b>
将其视为指针。因此,当您修改一个时,指向相同值的另一个也会更改。
Python中的copy method
returns一个shallow copy of a list
。
浅拷贝的意思是:对新列表的任何修改都不会影响原来的列表。
例如:
lis1=['a','b','c']
print(lis1)
lis2=lis1
print(lis2)
lis1.pop()
print(lis1, lis2)
输出为:
['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b'] ['a', 'b']
在此示例中,lis1
和 lis2
指的是同一个地址。因此,其中任何一个的任何变化都会导致另一个的变化。
我们可以使用list的copy method
或者copy module
.
来解决这个问题
例如:
lis1=['a','b','c']
print(lis1)
lis2=lis1.copy()
print(lis2)
lis1.pop()
print(lis1, lis2)
输出:
['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b'] ['a', 'b', 'c']
在此示例中,lis2
是存储在不同地址的 lis1
的副本,因此当我们更改 lis1
时,lis2
中没有任何变化。
同样也可以使用复制模块。例如:
import copy
lis1=['a','b','c']
print(lis1)
lis2=copy.copy(lis1)
print(lis2)
lis1.pop()
print("list1=",lis1,"list2=", lis2)
输出:
['a', 'b', 'c']
['a', 'b', 'c']
list1= ['a', 'b'] list2= ['a', 'b', 'c']
同样可以使用 copy method
.
解决您的问题
class Test:
def __init__(self, lis: list):
self.list = lis
lis = [1, 2, 3]
obj1 = Test(lis)
obj2 = Test(lis)
obj2new=obj2.list.copy()
print(obj1 is obj2)
print(obj1.list is obj2.list)
obj1.list.reverse()
print(obj2new)
现在,返回了所需的输出:
False
True
[1, 2, 3]
希望对您有所帮助!
考虑以下示例:
class Test:
def __init__(self, lis: list):
self.list = lis
lis = [1, 2, 3]
obj1 = Test(lis)
obj2 = Test(lis)
print(obj1 is obj2)
print(obj1.list is obj2.list)
obj1.list.reverse()
print(obj2.list)
输出:
False
True
[3, 2, 1]
解释:
我创建了2个相同的对象class,每个对象的“列表”是[1, 2, 3]
。测试名称 obj1
、obj2
是否引用同一个对象,答案是否定的 (False)。但是当我测试 obj1.list is obj2.list
时,当我反转名称 obj1
的列表时,我们得到 'True
' 作为 answer.Thus,该列表也反转了名称 obj2
,因为它是两个名称的相同列表。
我需要一种方法来反转 obj1
的列表,而不是 obj2
。所以我需要创建一个新列表。
最后会是这样的结果:
obj1.list.reverse()
print(obj2.list)
预期输出:
[1, 2, 3]
您正在 self.list
中存储对列表的相同引用,您可以通过复制来避免这种情况:
class Test:
def __init__(self, lis: list):
self.list = <b>lis[:]</b>
将其视为指针。因此,当您修改一个时,指向相同值的另一个也会更改。
Python中的copy method
returns一个shallow copy of a list
。
浅拷贝的意思是:对新列表的任何修改都不会影响原来的列表。
例如:
lis1=['a','b','c']
print(lis1)
lis2=lis1
print(lis2)
lis1.pop()
print(lis1, lis2)
输出为:
['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b'] ['a', 'b']
在此示例中,lis1
和 lis2
指的是同一个地址。因此,其中任何一个的任何变化都会导致另一个的变化。
我们可以使用list的copy method
或者copy module
.
例如:
lis1=['a','b','c']
print(lis1)
lis2=lis1.copy()
print(lis2)
lis1.pop()
print(lis1, lis2)
输出:
['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b'] ['a', 'b', 'c']
在此示例中,lis2
是存储在不同地址的 lis1
的副本,因此当我们更改 lis1
时,lis2
中没有任何变化。
同样也可以使用复制模块。例如:
import copy
lis1=['a','b','c']
print(lis1)
lis2=copy.copy(lis1)
print(lis2)
lis1.pop()
print("list1=",lis1,"list2=", lis2)
输出:
['a', 'b', 'c']
['a', 'b', 'c']
list1= ['a', 'b'] list2= ['a', 'b', 'c']
同样可以使用 copy method
.
class Test:
def __init__(self, lis: list):
self.list = lis
lis = [1, 2, 3]
obj1 = Test(lis)
obj2 = Test(lis)
obj2new=obj2.list.copy()
print(obj1 is obj2)
print(obj1.list is obj2.list)
obj1.list.reverse()
print(obj2new)
现在,返回了所需的输出:
False
True
[1, 2, 3]
希望对您有所帮助!