相等字符串自动更新(列表对象参考)
Equal strings auto updating (List object reference)
我最近参加了一次大学考试,有人问我这个程序的输出是什么:
def fun(x):
y=x
x.append(4)
print(str(x)+" "+str(y))
fun(["one","two",3,5.0])
我回答说 y 列表将是 ["one","two", 3,5.0]
,在向其附加 4 之后,x 列表将是相同的,但在它的末尾有一个 4。令我惊讶的是,当我打印两个列表时,它们是相等的,即使 x 列表更新是在两个列表之间建立相等性之后执行的。为什么会这样?
谢谢
实际上 x
和 y
是引用对象的标签,因此当您分配 y=x
时,您创建了 2 个对一个对象的引用,因此当您更改其中一个时,您更改了主要对象 .
您可能还注意到 x
, y
是局部变量,当您进行就地更改时 append
您更改了主对象,但是如果您使用赋值 python 创建一个新对象:
>>> def fun(x):
... y=x
... x=x+[3]
... print(str(x)+" "+str(y))
...
>>> fun(["one","two",3,5.0])
['one', 'two', 3, 5.0, 3] ['one', 'two', 3, 5.0]
对象的就地更改不会将名称归类为本地名称;只有真实姓名
任务做。例如,如果名称 L 被分配给一个列表的顶层
模块,函数中的语句 L = X
会将 L 归类为局部,但 L.append(X)
将不会。在后一种情况下,我们正在更改 L 引用的列表对象,而不是 L 本身——
像往常一样在全局范围内找到 L,并且 Python 愉快地修改它而不需要
全局(或 nonlocal
)声明。像往常一样,它有助于保持两者之间的区别
名称和对象清晰:更改对象不是对名称的赋值。(来自 mark lutzpython 的学习)
class A:
global L
L=[1,2]
def b(self):
L=[0,0]
return L
def c(self):
L.append(5)
return L
a=A()
print a.b()
print a.c()
结果:
[0, 0]
[1, 2, 5]
如果列出 x 到 y,您已给出参考。因此列表 x 中的任何更改也会影响列表 y。
y=x
例如:
>>> x = ["one","two",3,5.0]
>>> y = x
>>> x[3] = 4
>>> x
['one', 'two', 3, 4]
>>> y
['one', 'two', 3, 4]
这里x和y有相同的身份。
>>> x is y
True
>>> id(x)
3073118540L
>>> id(y)
3073118540L
您可以使用 swampy 模块更好地理解这一点:
>>> from swampy.Lumpy import Lumpy
>>> lump = Lumpy()
>>> x = ["one","two",3,5.0]
>>> y = x
>>> x[3] = 4
>>> lump.object_diagram()
可以通过将列表 x 复制到列表 y 来实现您所期望的,如下所示:
>>> x = ["one","two",3,5.0]
>>> y = x[:]
>>> x.pop()
5.0
>>> x
['one', 'two', 3]
>>> y
['one', 'two', 3, 5.0]
因此,通过将内容从 x 复制到 y,它们不具有相同的身份:
>>> id(x)
3073240428L
>>> id(y)
3073240588L
>>> x is y
False
使用沼泽:
>>> from swampy.Lumpy import Lumpy
>>> lump = Lumpy()
>>> x = ["one","two",3,5.0]
>>> y = x[:]
>>> lump.draw_object()
>>> lump.object_diagram()
如需更好的解释,请访问此处How do I copy an object in Python?
因为列表是 mutable
个对象。参见 Python Data Model
In [1]: a = [1]
In [3]: b = a
In [4]: b
Out[4]: [1]
In [5]: b.append(2)
In [6]: a
Out[6]: [1, 2]
In [7]: b
Out[7]: [1, 2]
In [8]: id(a), id(b)
Out[8]: (140260765233376, 140260765233376)
因为名称 y
绑定到与 x
相同的列表
y = x
这幅画非常棒:
x y
| /
| /
["one", "two", 3, 5.0]
x.append(4)
x y
| /
| /
["one", "two", 3, 5.0, 4]
您可以尝试以下示例。它将帮助您了解赋值运算符和复制(浅)、深度复制等方法之间的区别。
>>> import copy
>>> l1 = [1,2, [1,2]]
>>> l1
[1, 2, [1, 2]]
#Create l2, l3, l4 by copy, deepcopy method and normal assignment.
>>> l2 = copy.copy(l1)
>>> l3 = copy.deepcopy(l1)
>>> l4 = l1
>>> l2
[1, 2, [1, 2]]
>>> l3
[1, 2, [1, 2]]
>>> l4
>>> [1, 2, [1, 2]]
#-----------------------Now Append value to l1
>>> l1.append(9)
>>> l1
[1, 2, [1, 2], 9]
>>> l2
[1, 2, [1, 2]]
>>> l3
[1, 2, [1, 2]]
>>> l4
>>> [1, 2, [1, 2], 9]
#-----------------------Now Append value to l1[2]
>>> l1[2].append(5)
>>> l1
[1, 2, [1, 2, 5], 9]
>>> l2
[1, 2, [1, 2, 5]]
>>> l3
[1, 2, [1, 2]]
>>> l4
>>> [1, 2, [1, 2, 5], 9]
#------------------------
我最近参加了一次大学考试,有人问我这个程序的输出是什么:
def fun(x):
y=x
x.append(4)
print(str(x)+" "+str(y))
fun(["one","two",3,5.0])
我回答说 y 列表将是 ["one","two", 3,5.0]
,在向其附加 4 之后,x 列表将是相同的,但在它的末尾有一个 4。令我惊讶的是,当我打印两个列表时,它们是相等的,即使 x 列表更新是在两个列表之间建立相等性之后执行的。为什么会这样?
谢谢
实际上 x
和 y
是引用对象的标签,因此当您分配 y=x
时,您创建了 2 个对一个对象的引用,因此当您更改其中一个时,您更改了主要对象 .
您可能还注意到 x
, y
是局部变量,当您进行就地更改时 append
您更改了主对象,但是如果您使用赋值 python 创建一个新对象:
>>> def fun(x):
... y=x
... x=x+[3]
... print(str(x)+" "+str(y))
...
>>> fun(["one","two",3,5.0])
['one', 'two', 3, 5.0, 3] ['one', 'two', 3, 5.0]
对象的就地更改不会将名称归类为本地名称;只有真实姓名
任务做。例如,如果名称 L 被分配给一个列表的顶层
模块,函数中的语句 L = X
会将 L 归类为局部,但 L.append(X)
将不会。在后一种情况下,我们正在更改 L 引用的列表对象,而不是 L 本身——
像往常一样在全局范围内找到 L,并且 Python 愉快地修改它而不需要
全局(或 nonlocal
)声明。像往常一样,它有助于保持两者之间的区别
名称和对象清晰:更改对象不是对名称的赋值。(来自 mark lutzpython 的学习)
class A:
global L
L=[1,2]
def b(self):
L=[0,0]
return L
def c(self):
L.append(5)
return L
a=A()
print a.b()
print a.c()
结果:
[0, 0]
[1, 2, 5]
如果列出 x 到 y,您已给出参考。因此列表 x 中的任何更改也会影响列表 y。
y=x
例如:
>>> x = ["one","two",3,5.0]
>>> y = x
>>> x[3] = 4
>>> x
['one', 'two', 3, 4]
>>> y
['one', 'two', 3, 4]
这里x和y有相同的身份。
>>> x is y
True
>>> id(x)
3073118540L
>>> id(y)
3073118540L
您可以使用 swampy 模块更好地理解这一点:
>>> from swampy.Lumpy import Lumpy
>>> lump = Lumpy()
>>> x = ["one","two",3,5.0]
>>> y = x
>>> x[3] = 4
>>> lump.object_diagram()
可以通过将列表 x 复制到列表 y 来实现您所期望的,如下所示:
>>> x = ["one","two",3,5.0]
>>> y = x[:]
>>> x.pop()
5.0
>>> x
['one', 'two', 3]
>>> y
['one', 'two', 3, 5.0]
因此,通过将内容从 x 复制到 y,它们不具有相同的身份:
>>> id(x)
3073240428L
>>> id(y)
3073240588L
>>> x is y
False
使用沼泽:
>>> from swampy.Lumpy import Lumpy
>>> lump = Lumpy()
>>> x = ["one","two",3,5.0]
>>> y = x[:]
>>> lump.draw_object()
>>> lump.object_diagram()
如需更好的解释,请访问此处How do I copy an object in Python?
因为列表是 mutable
个对象。参见 Python Data Model
In [1]: a = [1]
In [3]: b = a
In [4]: b
Out[4]: [1]
In [5]: b.append(2)
In [6]: a
Out[6]: [1, 2]
In [7]: b
Out[7]: [1, 2]
In [8]: id(a), id(b)
Out[8]: (140260765233376, 140260765233376)
因为名称 y
绑定到与 x
y = x
这幅画非常棒:
x y
| /
| /
["one", "two", 3, 5.0]
x.append(4)
x y
| /
| /
["one", "two", 3, 5.0, 4]
您可以尝试以下示例。它将帮助您了解赋值运算符和复制(浅)、深度复制等方法之间的区别。
>>> import copy
>>> l1 = [1,2, [1,2]]
>>> l1
[1, 2, [1, 2]]
#Create l2, l3, l4 by copy, deepcopy method and normal assignment.
>>> l2 = copy.copy(l1)
>>> l3 = copy.deepcopy(l1)
>>> l4 = l1
>>> l2
[1, 2, [1, 2]]
>>> l3
[1, 2, [1, 2]]
>>> l4
>>> [1, 2, [1, 2]]
#-----------------------Now Append value to l1
>>> l1.append(9)
>>> l1
[1, 2, [1, 2], 9]
>>> l2
[1, 2, [1, 2]]
>>> l3
[1, 2, [1, 2]]
>>> l4
>>> [1, 2, [1, 2], 9]
#-----------------------Now Append value to l1[2]
>>> l1[2].append(5)
>>> l1
[1, 2, [1, 2, 5], 9]
>>> l2
[1, 2, [1, 2, 5]]
>>> l3
[1, 2, [1, 2]]
>>> l4
>>> [1, 2, [1, 2, 5], 9]
#------------------------