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

请教一个 Python 中 for in 列表修改值的问题

  •  
  •   jonathanchoo · 2021-04-24 09:37:16 +08:00 · 2136 次点击
    这是一个创建于 1319 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码如下:

    case1: 
    lists = []
    
    v1 = {"name": "aa", "age": 18}
    lists.append(v1)
    
    for v in lists:
        v["name"] = "bb"
    
    print(lists) //[{'name': 'bb', 'age': 18}]
    
    
    case2:
    list2 = []
    
    v2 = "a"
    list2.append(v2)
    
    for v in list2:
        v = "b"
    
    print(list2) //a
    

    按我的理解,for in 出来的 value 不应该是第二种情况,属于值拷贝吗,为什么在 case1 中,可以直接修改 list 中的值啊,是因为 list 中的字典类型是引用类型吗?

    11 条回复    2021-04-25 13:49:28 +08:00
    crclz
        1
    crclz  
       2021-04-24 09:53:38 +08:00
    是的。其他语言会得出同样的结论。
    qgb
        2
    qgb  
       2021-04-24 09:59:10 +08:00   ❤️ 1
    str 是不可变对象,直接赋值 v 没有修改 list2,只是把 v 换了一个对象。你在 case1 中直接赋值 v={} 也是一样的
    laike9m
        3
    laike9m  
       2021-04-24 10:10:14 +08:00   ❤️ 2
    你不能以 C/C++ 的思维模型来理解 Python 的变量
    可以参考: http://foobarnbaz.com/2012/07/08/understanding-python-variables/
    hxysnail
        4
    hxysnail  
       2021-04-24 10:32:27 +08:00   ❤️ 1
    这个问题需要在 Python 对象模型中找答案,Python 对象都是通过指针引用的。Python 中的变量,可以理解成一个与变量名绑定在一起的对象指针。

    case1 中,临时变量 v 引用列表保存的 dict 对象,然后对 dict 对象进行修改,也就是对列表中的对象进行修改。case2 中,临时变量一开始引用列表中保存的 string 对象,但后来修改临时变量将它指向一个新对象,列表引用的对象没有任何变化。

    关于 Python 对象模型,可以参考这个系列: https://fasionchan.com/python-source/object-model/overview/
    ClericPy
        5
    ClericPy  
       2021-04-24 10:40:51 +08:00
    jonathanchoo
        6
    jonathanchoo  
    OP
       2021-04-24 11:00:59 +08:00 via iPhone
    @hxysnail
    @laike9m
    获益匪浅,非常感谢!
    johnsona
        7
    johnsona  
       2021-04-24 17:00:10 +08:00 via iPhone
    变量就是一个标签
    两个例子分别指向一个你的列表 和你新创建的字符串
    IgniteWhite
        8
    IgniteWhite  
       2021-04-24 19:02:38 +08:00
    补充 Python 官方教程( The Python Tutorial, by Guido van Rossum 本人)里的选段,作为参考(我自己正好在读):

    https://docs.python.org/3/tutorial/classes.html#a-word-about-names-and-objects

    9.1. A Word About Names and Objects
    Objects have individuality, and multiple names (in multiple scopes) can be bound to the same object. This is known as aliasing in other languages. This is usually not appreciated on a first glance at Python, and can be safely ignored when dealing with immutable basic types (numbers, strings, tuples). However, aliasing has a possibly surprising effect on the semantics of Python code involving mutable objects such as lists, dictionaries, and most other types. This is usually used to the benefit of the program, since aliases behave like pointers in some respects. For example, passing an object is cheap since only a pointer is passed by the implementation; and if a function modifies an object passed as an argument, the caller will see the change — this eliminates the need for two different argument passing mechanisms as in Pascal.

    以及
    https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables

    As discussed in A Word About Names and Objects, shared data can have possibly surprising effects with involving mutable objects such as lists and dictionaries.
    James369
        9
    James369  
       2021-04-24 19:12:22 +08:00
    你举的两个例子,正好很好的说明了 Python 中可变对象和不可变对象的区别。
    madpecker009
        10
    madpecker009  
       2021-04-25 08:42:38 +08:00
    请不要尝试在循环中修改列表的值。其他语言同理
    duole
        11
    duole  
       2021-04-25 13:49:28 +08:00
    可变对象 和 不可变对象的原因。度娘查一下 python 不可变对象都有哪些吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1268 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 18:06 · PVG 02:06 · LAX 10:06 · JFK 13:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.