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
xjay
V2EX  ›  Python

求解,这段代码运行结果怎么跟我想的不同

  •  
  •   xjay · 2019-12-24 23:45:41 +08:00 · 3284 次点击
    这是一个创建于 1800 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概的代码是这样的

    def run(data):
        s = []
        for c in ['ccc', 'ddd']:
            data['c'] = c
            print(data)
            s.append(data)
    
        print(s)
    
    if __name__ == "__main__":
        run({'a': 'aaa', 'b': 'bbb'})
    

    然后我想得到的结果是

    {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}
    {'a': 'aaa', 'b': 'bbb', 'c': 'ddd'}
    [{'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}, {'a': 'aaa', 'b': 'bbb', 'c': 'ddd'}]
    

    但是结果却是

    {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}
    {'a': 'aaa', 'b': 'bbb', 'c': 'ddd'}
    [{'a': 'aaa', 'b': 'bbb', 'c': 'ddd'}, {'a': 'aaa', 'b': 'bbb', 'c': 'ddd'}]
    

    为什么?我的理解有错误吗?求解,我是被什么麻痹了?

    8 条回复    2019-12-25 15:09:58 +08:00
    jxxz
        1
    jxxz  
       2019-12-24 23:49:57 +08:00 via iPhone
    引用传递
    jxxz
        2
    jxxz  
       2019-12-24 23:51:26 +08:00 via iPhone
    append 的是两个相同的 data 字典对象,所以第二次 ddd 覆盖了第一次的 ccc
    jugelizi
        3
    jugelizi  
       2019-12-24 23:51:53 +08:00
    哈哈 这分词 bug
    你应该看下变量在内存里如何存放的
    melovto
        4
    melovto  
       2019-12-24 23:52:37 +08:00
    函数传的是引用 改变了外部变量
    wangyzj
        5
    wangyzj  
       2019-12-24 23:53:52 +08:00
    list 不是副本
    xjay
        6
    xjay  
    OP
       2019-12-25 00:32:28 +08:00
    @jxxz @jugelizi @melovto @wangyzj 谢谢各位,我已经知道为什么了
    CzaOrz
        7
    CzaOrz  
       2019-12-25 09:58:26 +08:00
    我也遇到过类似问题。并不是覆盖与被覆盖的关系,也不是引用了外部变量。
    造成这种现象是因为 list 和 dict 都是可变对象,是一种容器,对象被创建后内容可修改。

    在没有拷贝的前提下直接重复引用同一可变对像,结果多次引用都是指向的同一对象。
    一旦对`容器`进行了某些修改,就自然会造成所有引用的改变。
    (话说,还有一个浅拷贝和深拷贝的坑~)
    xjay
        8
    xjay  
    OP
       2019-12-25 15:09:58 +08:00
    @CzaOrz 谢谢,这个解释应该是最准确的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5963 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 02:50 · PVG 10:50 · LAX 18:50 · JFK 21:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.