V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
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
meteordragon
V2EX  ›  Python

小白发现一个 dict 的奇怪现象,请问有什么办法可以避免

  •  
  •   meteordragon · May 9, 2021 · 4236 views
    This topic created in 1820 days ago, the information mentioned may be changed or developed.
    dd={"a":"1","b":"2"}
    cc=dd
    cc["c"]="3"
    print(dd)
    print(cc)

    运行结果是
    {'a': '1', 'b': '2', 'c': '3'}
    {'a': '1', 'b': '2', 'c': '3'}

    改变 cc 的值同时改变 dd 的值
    list 变量有同样的问题
    但是我他赋值给另一个变量的目的就是不改变它的值啊。请问有什么办法避免这个问题吗?还是说是我的 python 环境有问题呢?
    21 replies    2021-07-17 08:31:27 +08:00
    Jakarta
        1
    Jakarta  
       May 9, 2021
    python 深拷贝 浅拷贝
    mcoo1997
        2
    mcoo1997  
       May 9, 2021 via Android
    import copy
    copy.deepcopy(cc)
    jmc891205
        3
    jmc891205  
       May 9, 2021
    cc = dict(dd)
    di94sh
        4
    di94sh  
       May 9, 2021 via iPhone   ❤️ 1
    python 基础知识 可变对象与不可变对象
    mostkia
        5
    mostkia  
       May 9, 2021
    一般的赋值操作,只是拷贝了目标对象的一个内存地址的引用,类似安装的程序,你只拷贝了一个快捷方式,程序被删了或改变了,所有的快捷方式都会跟着失效变动,js 语言也有这类问题,尝试用深拷贝。
    ch2
        6
    ch2  
       May 9, 2021
    c#+js+python 都是这样
    xiri
        7
    xiri  
       May 9, 2021   ❤️ 1
    改成 cc=dd.copy() 就行了,这是很基础的问题,深浅拷贝
    meteordragon
        8
    meteordragon  
    OP
       May 9, 2021
    感谢各位前辈,之前真没注意过这个问题
    jotpot
        9
    jotpot  
       May 9, 2021
    确实是小白。所有的编程语言都有引用和 clone 的问题
    nightwitch
        10
    nightwitch  
       May 9, 2021
    引用语义和值语义的差别,不同语言有不同的倾向。
    muzuiget
        11
    muzuiget  
       May 10, 2021
    引用问题,建议把基础部分重看一次。
    littlewey
        12
    littlewey  
       May 10, 2021 via iPhone
    看一下
    id(cc)
    id(dd)
    wd
        13
    wd  
       May 10, 2021 via iPhone
    感觉隔一段时间就有人来这里说说这个问题...
    HashV2
        14
    HashV2  
       May 10, 2021
    我一周看到三四次这个问题了,在不同的语言节点。。
    no1xsyzy
        15
    no1xsyzy  
       May 10, 2021
    应该不算深浅拷贝问题,而是拷贝与引用的问题。

    但我觉得你的需求更大可能应该写成
    cc = {**dd, "c":"3"}
    展开式浅拷贝同时进行修改是非常好用的糖

    @jotpot 略暴言。C 语言没有引用与 clone 的问题,都是 clone,只不过 clone 的可能是指针(地址)。你若是非要传参传 struct 而不是 struct* 也给你全量拷贝了(通常没人这么用罢了)。Pascal 类似。
    函数式语言也不会遇到这个问题,因为全都不可变了,就没引用和 clone 的差异了。
    Kilerd
        16
    Kilerd  
       May 10, 2021
    这是 python 有史以来的 bug,建议换一门语言以避免同样的 bug
    RRRoger
        17
    RRRoger  
       May 10, 2021
    百度谷歌随便一搜就有解决方案
    charlie21
        18
    charlie21  
       May 10, 2021 via iPhone
    “(用等号)赋值给另一个变量的目的就是不改变它的值”
    这个目的没错,但只限于值类型的变量。
    参考 v2ex.com/t/774968 24 楼 PHP 语言
    ddzzhen
        19
    ddzzhen  
       May 10, 2021 via Android
    赋值操作是链接,占用内存不增加
    xiaoxinshiwo
        20
    xiaoxinshiwo  
       May 11, 2021
    [捂眼睛]
    FurN1
        21
    FurN1  
       Jul 17, 2021
    @xiri cc=dd.copy() 也是浅拷贝。
    @jmc891205 cc=dict(dd) 也是浅拷贝。
    只有 @mcoo1997 在二楼使用 copy.deepcopy()是深拷贝。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   998 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 65ms · UTC 17:59 · PVG 01:59 · LAX 10:59 · JFK 13:59
    ♥ Do have faith in what you're doing.