python - `b = a` 是否使 `b` 成为同一个对象?为什么?

标签 python list

<分区>

为什么我在 REPL 得到这个结果?

>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True

我的理解是 is 仅在两个变量指向同一个对象时才计算为 True,在这种情况下,它们是具有相同值的不同对象。 == 会评估为 True,但 is 不应该。

更进一步:

>>> b.reverse()
>>> (a, b)
([3, 2, 1], [3, 2, 1])

在解释器看来,它们同一个对象,对b的操作会自动对a进行。再一次,为什么?

最佳答案

a = [81, 82, 83]
b = a
print(a is b) #prints True

这是实际发生的事情:

enter image description here

对于类似的东西:

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

print(a is b) # False

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

enter image description here

In [24]: import sys

In [25]: a=[1,2,3]

In [26]: sys.getrefcount(a) #number of references to [1,2,3] are 2
Out[26]: 2

In [27]: b=a       #now b also points to [1,2,3]

In [28]: sys.getrefcount(a)   # reference to [1,2,3] got increased by 1,
                              # as b now also points to [1,2,3]
Out[28]: 3

In [29]: id(a)
Out[29]: 158656524      #both have the same id(), that's why "b is a" is True

In [30]: id(b)
Out[30]: 158656524

何时使用 copy模块:

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   

关于python - `b = a` 是否使 `b` 成为同一个对象?为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12689312/

相关文章:

python - Django 获取列表中每个值的最后一个对象

python - 如何通过Panda导入几年但特定月份的数据?

python - 错误的默认 python 命令

list - 从dart中的arraylist排列相同的自定义对象

list - 将 foldl 写为 foldr 混淆

python - Numpy 错误 : underflow encountered in exp

python - 如何根据属性访问类型(使用类或实例)在函数之间创建 "switch"?

python - 根据 Python 中的一组索引将列表拆分为多个部分

list - 可以给自己添加一个 data.frame 吗?

c# - 排序列表并在排序后将特定元素保留在列表末尾