V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Phishion
V2EX  ›  Python

请问浅拷贝多次和深拷贝一次是否存在结果上的区别?

  •  
  •   Phishion · 2019-12-05 17:18:22 +08:00 · 2949 次点击
    这是一个创建于 1810 天前的主题,其中的信息可能已经有所发展或是发生改变。

    从结果来讲性能差别巨大,本质上 2 种方式拿到的都是完全不一样的副本才对。 那么是不是可以认为这跟列表推导一样是一种优化写法?如果这样的话,那么深拷贝的意义在哪呢?是为了极端条件下使用方便么?为什么比起手动递归性能损失那么多?

    import time,copy
    li = [i for i in range(10000000)]
    xr = [i for i in range(10000000)]
    li.append(xr)
    
    # 方式 1:浅拷贝
    st1 = time.process_time()
    temp1 = copy.copy(li)
    temp1[-1] = copy.copy(li[-1])
    end1 = time.process_time()
     
    # 方式 2:深拷贝
    start2 = time.process_time()
    temp3 = copy.deepcopy(li)
    end2 = time.process_time()
     
    print("方式 1 耗时:%s" % (end1 - st1))
    print("方式 2 耗时:%s" % (end2 - start2))
    

    `方式 1 耗时:0.2146999999999999

    `方式 2 耗时:12.704364

    7 条回复    2019-12-05 18:17:56 +08:00
    Heebe
        1
    Heebe  
       2019-12-05 17:25:03 +08:00
    那要看具体的业务逻辑需求
    A.b.c
    假设浅拷贝 A 到 B,那么复制的 B.b == A.b
    如果是深拷贝,B.b != A.b,也就是子类会继续拷贝(可以认为是递归,直到所有都是结构体)
    monsterxx03
        2
    monsterxx03  
       2019-12-05 17:25:51 +08:00
    l = [[1,2]]
    l1 = l.copy()
    l1[0][0] = 2
    print(l1) # [[2,2]]
    print(l) # [[2,2]]

    浅拷贝不会复制嵌套的对象, 修改内部对象值,原对象也会变的
    zixiaoguan
        3
    zixiaoguan  
       2019-12-05 17:27:58 +08:00
    看你业务想要修改的数据在哪一层了,一般而言既然想修改的东西不想影响到其他,直接深拷贝就好啦,方便维护,不易出错。前端不要想太多的性能问题啦。
    Heebe
        4
    Heebe  
       2019-12-05 17:29:22 +08:00   ❤️ 1
    @Heebe 补充,深拷贝和手写递归哪个性能优秀这个不用想,递归传递变量是已知变量名对象等,省略了查找和类型转换等,速度肯定会高一些的。所以,要看场景,如果是游戏服务器或者压力比较大的场景,有时候自己写一个会更加直接有效,如果是一些单机或者是不会太吃消耗的,深拷贝可以加快开发速度。另外还有一些场景,比如为止变量名、匿名等等。
    Phishion
        5
    Phishion  
    OP
       2019-12-05 17:30:01 +08:00
    @monsterxx03 我知道不会复制嵌套对象,问题是我深拷贝处理性能非常差,浅拷贝手动递归和深拷贝在效果上一样的,但是性能节省非常多,这就很奇怪
    zixiaoguan
        6
    zixiaoguan  
       2019-12-05 18:04:34 +08:00
    通过调试这个属于时间复杂度的问题 具体你自己从 10W 开始调一下就知道了。因为深拷贝会给每个对象进行拷贝,而这个操作时遍历的,所以浅拷贝你的代码只拷贝 2 次,而深拷贝拷贝了 10000001 次。
    zarte
        7
    zarte  
       2019-12-05 18:17:56 +08:00
    深拷贝要分配空间并存入数据,浅拷贝只要指针指下。等你浅拷贝有问题的时候就需要深拷贝了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3851 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 10:27 · PVG 18:27 · LAX 02:27 · JFK 05:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.