Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:两个对象是相同的_Python_List - Fatal编程技术网

Python:两个对象是相同的

Python:两个对象是相同的,python,list,Python,List,可能重复: 此代码打印为True。为什么?只有当两个变量指向同一个对象时,“is”才会返回True,而在本例中,这两个变量是具有相同值的不同对象。“==”将返回True,但“is”不应返回True 但是, b.reverse() print a,b 打印[3,2,1][3,2,1],似乎就解释器而言,它们是同一个对象,对b的操作将自动对a执行。再说一遍,为什么?我以前从未见过这样的事情发生。它们实际上引用的是同一个对象 试试这个: a = [1,2,3] b = a print b is a

可能重复:

此代码打印为True。为什么?只有当两个变量指向同一个对象时,“is”才会返回True,而在本例中,这两个变量是具有相同值的不同对象。“==”将返回True,但“is”不应返回True

但是,

b.reverse()
print a,b

打印[3,2,1][3,2,1],似乎就解释器而言,它们是同一个对象,对b的操作将自动对a执行。再说一遍,为什么?我以前从未见过这样的事情发生。

它们实际上引用的是同一个对象

试试这个:

a = [1,2,3]
b = a
print b is a
b[0] = 0
print b is a
您将看到a和b都已更改,并且彼此仍然相同

a = [1,2,3]
b = a
print b is a
您正在比较对同一
列表的引用。如果您执行以下操作:

a = [1,2,3]
b = [1,2,3]
print b is a
你应该得到一个假的

a = [81, 82, 83]
b = a
print(a is b) #prints True
这就是这里实际发生的情况:

比如:

a = [81,82,83]
b = [81,82,83]

print(a is b) # False

print(a == b)  #True, as == only checks value equality

何时使用该模块:

有关详细信息:

In [32]: def func():
   ....:     a=[1,2,3]
   ....:     b=a
   ....:     
   ....:     

In [34]: import dis

In [35]: dis.dis(func)
  2           0 LOAD_CONST               1 (1)
              3 LOAD_CONST               2 (2)
              6 LOAD_CONST               3 (3)
              9 BUILD_LIST               3
             12 STORE_FAST               0 (a)   #now 'a' poits to [1,2,3]

  3          15 LOAD_FAST                0 (a)    #load the object referenced by a
             18 STORE_FAST               1 (b)    #store the object returned by a to b 
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        

In [36]: def func1():
   ....:     a=[1,2,3]
   ....:     b=[1,2,3]
   ....:     
   ....:     

In [37]: dis.dis(func1)      #here both a and b are loaded separately
  2           0 LOAD_CONST               1 (1)
              3 LOAD_CONST               2 (2)
              6 LOAD_CONST               3 (3)
              9 BUILD_LIST               3
             12 STORE_FAST               0 (a)

  3          15 LOAD_CONST               1 (1)
             18 LOAD_CONST               2 (2)
             21 LOAD_CONST               3 (3)
             24 BUILD_LIST               3
             27 STORE_FAST               1 (b)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE   

我不确定列表的工作原理是否相同,但请看一看有关浅拷贝和深拷贝的numpy.array()教程:

a=b
只是创建对同一对象的新引用。要获得真正的副本,您可能会发现列表对象与链接中的深度副本示例类似,因此
b=a.copy()
。然后可以说有两个引用指向两个具有相同值的独立对象


另外,我认为大多数OO语言都是这样工作的,
=
只是创建了一个新引用,而不是一个新对象。

当您执行
a=[1,2,3]
时,您将名称
a
绑定到一个列表对象。当您执行
b=a
时,您将把名称
b
绑定到
a
是什么-在本例中是列表对象。因此,他们是一样的。。。一个对象可以有多个名称。这本书值得在网上阅读

如果您想制作listobj的副本,那么您可以查看
b=a[:]
使用slice创建浅层副本,或者查看
copy.copy
创建浅层副本(应适用于任意对象),或者查看
copy.deepcopy
创建奇怪的深度副本

您还将注意到CPython中缓存短字符串/小整数的惊人之处

>>> a = 4534534
>>> b = a
>>> a is b
True
>>> b = 4534534
>>> a is b
False
>>> a = 1
>>> b = a
>>> a is b
True
>>> b = 1
>>> a is b
True
此代码打印为True。为什么?

因为
b是一个

仅当两个变量指向同一对象时,“is”才返回True

如果它们命名相同的对象。“指向”是一个粗俗的术语,暗指一个低得多的编程模型

在这种情况下,它们是具有相同值的不同对象

不,他们不是

在Python中,
b=a
意味着“
b
将不再是当前名称的名称(如果有的话),而成为当前名称的名称”。同一个物体。没有复印件

Python中不会隐式复制内容

打印[3,2,1][3,2,1],似乎就解释器而言,它们是同一个对象

因为他们是

b上的操作将自动在a上执行

因为它们是同一个物体

再说一遍,为什么

再说一次,因为他们是

…就好像你想到了每一个明显的测试来证实你的行为,但是一旦每一个测试都与你的核心假设相矛盾,你就拒绝拒绝拒绝你的核心假设,即使文献中没有任何东西支持你的核心假设(因为事实上它是错误的)

我以前从未见过这样的事情发生


那么您以前一定从未在Python中测试过类似的东西,因为在Python中它一直都是这样工作的。编程语言之间甚至没有那么奇怪;Java对所有不是基元类型的东西都做同样的事情,C#对类(引用类型)做同样的事情,而对结构(值类型)做你显然期望的事情。它被称为“引用语义”,这绝不是一个新概念。

“在这种情况下,它们是具有相同值的不同对象”我认为不是。是时候让您更好地学习Python了
a
是对列表
[1,2,3]
的引用,
b=a
a
中包含的引用分配给
b
,因此现在它们包含对同一列表的引用。感谢您的快速响应。我尝试了a=[1,2,3]b=[1,2,3],这就解决了这个问题,但是对于我正在编写的代码来说,这是行不通的。如何让解释器知道,我想让它考虑一个和B不同的对象,这样B rReSESER()不改变一个“jjkneCKiE<代码> B= A[:]:/Cult>(浅拷贝)尝试复制类:@ JaveKeCKI:Cudio> [B:A[:] /<代码>将对简单列表进行操作,但是在列表的情况下,您需要<代码> Debug()
来自
复制
模块。您需要副本做什么?你到底想做什么,为什么不问这个问题呢?你能解释一下为什么最后一个案例是真的吗?它看起来不一致,那么为什么它是这样设计的呢?在我看来,似乎只适用于整数btw(包括)-5到256,这是一个奇数间隔。@dan它也适用于单个字符(部分原因是256)。因为字符串和整数是不可变的,所以只保留一个常用值的副本是有意义的-5可能用于处理一些常见的错误代码,0和1经常使用,对于短循环或按位运算,0..256是有意义的。。。
In [1]: a=[1,2,3]

In [2]: b=a

In [3]: id(a),id(b)        
Out[3]: (143186380, 143186380)   #both point to the same object

In [4]: b=a[:]                #now use slicing, it is equivalent to b=copy.copy(a)
                              # or b= list(a)    

In [5]: id(a),id(b)
Out[5]: (143186380, 143185260)     #as expected both now point to different objects
                                   # so now changing one will not affect other

In [6]: a=[[1,2],[3,4]]          #list of lists

In [7]: b=a[:]                   #use slicing

In [8]: id(a),id(b)            #now both point to different object as expected
                               # But what about the internal lists?
Out[8]: (143184492, 143186380)

In [11]: [(id(x),id(y)) for (x,y) in zip(a,b)]   #so internal list are still same objects
                                                 #so doing a[0][3]=5, will changes b[0] too
Out[11]: [(143185036, 143185036), (143167244, 143167244)]

In [12]: from copy import deepcopy            #to fix that use deepcopy

In [13]: b=deepcopy(a)

In [14]: [(id(x),id(y)) for (x,y) in zip(a,b)]    #now internal lists are different too
Out[14]: [(143185036, 143167052), (143167244, 143166924)]
In [32]: def func():
   ....:     a=[1,2,3]
   ....:     b=a
   ....:     
   ....:     

In [34]: import dis

In [35]: dis.dis(func)
  2           0 LOAD_CONST               1 (1)
              3 LOAD_CONST               2 (2)
              6 LOAD_CONST               3 (3)
              9 BUILD_LIST               3
             12 STORE_FAST               0 (a)   #now 'a' poits to [1,2,3]

  3          15 LOAD_FAST                0 (a)    #load the object referenced by a
             18 STORE_FAST               1 (b)    #store the object returned by a to b 
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        

In [36]: def func1():
   ....:     a=[1,2,3]
   ....:     b=[1,2,3]
   ....:     
   ....:     

In [37]: dis.dis(func1)      #here both a and b are loaded separately
  2           0 LOAD_CONST               1 (1)
              3 LOAD_CONST               2 (2)
              6 LOAD_CONST               3 (3)
              9 BUILD_LIST               3
             12 STORE_FAST               0 (a)

  3          15 LOAD_CONST               1 (1)
             18 LOAD_CONST               2 (2)
             21 LOAD_CONST               3 (3)
             24 BUILD_LIST               3
             27 STORE_FAST               1 (b)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE   
>>> a = 4534534
>>> b = a
>>> a is b
True
>>> b = 4534534
>>> a is b
False
>>> a = 1
>>> b = a
>>> a is b
True
>>> b = 1
>>> a is b
True