Python - 深拷贝一个带有指向自身引用的列表,会报错么?紧接着用==比较,会报错么?

发布时间 2023-10-12 16:58:17作者: frank_cui

问题描述

深拷贝一个带有指向自身引用的列表:

  • 列表 x 中有指向自身的引用,因此 x 是一个无限嵌套的列表。
import copy
x = [1]
x.append(x)

>>x
[1, [...]]

y = copy.deepcopy(x)
>>y
[1, [...]]

 

深拷贝不报错

但是我们发现深度拷贝 x 到 y 后,程序并没有出现 stack overflow 的现象

其实,这是因为深度拷贝函数 deepcopy 中会维护一个字典,记录已经拷贝的对象与其 ID。拷贝过程中,如果字典里已经存储了将要拷贝的对象,则会从字典直接返回,我们来看相对应的源码就能明白:

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.
      
  See the module's __doc__ string for more info.
  """
  
    if memo is None:
        memo = {}
    d = id(x) # 查询被拷贝对象x的id
  y = memo.get(d, _nil) # 查询字典里是否已经存储了该对象
  if y is not _nil:
      return y # 如果字典里已经存储了将要拷贝的对象,则直接返回
        ...    

 

==会报错

'=='操作符则会递归地遍历对象的所有值,并逐一比较。而x是一个无限嵌套的列表,递归会无休无止下去,到达限定的层数,就会报错:

RecursionError: maximum recursion depth exceeded in comparison。