推荐学习书目
› 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
Alerta
V2EX  ›  Python

关于 Python 不使用临时变量来交换两个值的原理

  •  
  •   Alerta · Aug 26, 2018 · 8632 views
    This topic created in 2996 days ago, the information mentioned may be changed or developed.
    用其他语言交换两个值,而且不用临时变量不是用加减法就是用异或法,但是 python 就直接

    a,b =b,a

    即可

    我很好奇其中的原理是什么,我一开始的猜想是 Python 直接交换了 a,b 引用的内存地址,求各位大神解答
    28 replies  •  2018-08-27 15:30:39 +08:00
    huangzhe8263
    huangzhe8263
    Aug 26, 2018
    1
    b, a 返回的是一个 tuple
    然后 a, b 分别赋值为第一个和第二个
    就是
    (a, b) = (b, a)
    fwee
    fwee
    Aug 26, 2018
    2
    学一学编译和解释器的概念
    kkk330
    kkk330
    Aug 26, 2018 via iPhone❤️1
    3
    dis 看看
    Wincer
    Wincer
    Aug 26, 2018 via Android
    4
    Python 元组拆包,当 a, b = b, a 的时候,会把 b, a 看做一个可迭代对象,依次赋值给 a, b 组成的元组
    jmc891205
    jmc891205
    Aug 26, 2018
    5
    用 dis 看一看汇编就懂了
    wocanmei
    wocanmei
    Aug 26, 2018 via iPhone
    6
    个人觉得这只不过是一种语法糖,虽然没写中间变量底层说不定用了
    nazor
    nazor
    Aug 26, 2018
    7
    CAS
    hhsuan
    hhsuan
    Aug 26, 2018 via Android
    8
    如果是这么个问法,我觉得任何语言都可以不用变量交换两个值。
    codechaser
    codechaser
    Aug 26, 2018 via Android
    9
    unpacking,也就是多个产量负值时序列的拆包。简易写法
    zhicheng
    zhicheng
    Aug 26, 2018 via iPhone
    10
    虽然没有用临时变量,但是用了栈。
    adek06
    adek06
    Aug 26, 2018
    12
    同意一楼的说法
    Alerta
    Alerta
    OP
    Aug 26, 2018
    13
    @kkk330 dis 是??
    Yourshell
    Yourshell
    Aug 26, 2018 via iPhone
    14
    你没看到不代表不存在
    msg7086
    msg7086
    Aug 26, 2018❤️1
    15
    背后相当于做了:(伪代码)

    tmp = [a, b]
    a = tmp[1]
    b = tmp[0]

    和内存地址没什么关系。各种语言不同的写法最后都会被编译成类似的机器代码。
    Alerta
    Alerta
    OP
    Aug 26, 2018
    16
    感谢各位大神,原来答案不只是拆包。现在优化了之后,在 2、3 个值分配的时候是直接运用栈,在 3 个以上值分配的时候才是用了拆包的原理。
    详细答案在 11 楼哥们的链接里: https://stackoverflow.com/questions/21047524/how-does-swapping-of-members-in-the-python-tuples-a-b-b-a-work-internally
    momocraft
    momocraft
    Aug 26, 2018
    17
    都用 python 了就别想着"内存地址"了
    Feva
    Feva
    Aug 26, 2018
    18
    不爱思考的新手
    Yggdroot
    Yggdroot
    Aug 26, 2018
    19
    只是语法糖而已,如果有一种新的语言,甚至可以这样表示交换两个变量:
    `a<->b`
    Pythondr
    Pythondr
    Aug 26, 2018 via Android
    20
    元组的自动组包与自动解包
    inframe
    inframe
    Aug 26, 2018 via Android
    21
    python 是个栈机,push pop 一波搞定
    scriptB0y
    scriptB0y
    Aug 26, 2018
    22
    @wocanmei 其实没有用中间变量吧。

    只不过 Python 的解释器支持一个字节码,ROT_TWO,可以直接交换栈顶的两个变量。其他的语言没有这个功能而已。应该也不能叫做是语法糖。

    dis 查看方法:

    https://gist.github.com/laixintao/bb4330651c33124d52ff888b99c9e939

    Python ROT_TWO 文档:

    https://docs.python.org/3/library/dis.html#opcode-ROT_TWO

    ROT_TWO
    Swaps the two top-most stack items.

    cc @Alerta
    Joshua999
    Joshua999
    Aug 26, 2018 via Android
    23
    想知道只用加减法怎么实现,不用临时变量交换两个值
    Alerta
    Alerta
    OP
    Aug 26, 2018
    24
    @Joshua999 百度一下有很多
    Alerta
    Alerta
    OP
    Aug 26, 2018
    25
    @scriptB0y 感激感激
    unsized
    unsized
    Aug 27, 2018 via Android
    26
    a = a + b
    b = a - b
    a = a - b

    @Joshua999
    wocanmei
    wocanmei
    Aug 27, 2018 via iPhone
    27
    @scriptB0y #22 多谢科普
    Joshua999
    Joshua999
    Aug 27, 2018 via Android
    28
    @tyx1703 当时脑抽,看了半天没想出来,谢谢
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   577 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 22:38 · PVG 06:38 · LAX 14:38 · JFK 17:38
    ♥ Do have faith in what you're doing.