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

用其他语言交换两个值,而且不用临时变量不是用加减法就是用异或法,但是 python 就直接

a,b =b,a

即可

我很好奇其中的原理是什么,我一开始的猜想是 Python 直接交换了 a,b 引用的内存地址,求各位大神解答
关于 Python 中不使用临时变量来交换两个值的原理

29 回复

b, a 返回的是一个 tuple
然后 a, b 分别赋值为第一个和第二个
就是
(a, b) = (b, a)


这个帖子问的是Python里不用临时变量交换两个值的原理。其实这招在Python里特别简单,因为Python支持多重赋值(也叫元组解包)。

核心原理就是:

  1. 先把 a, b 打包成一个元组 (a, b)
  2. 然后把这个元组解包赋值给 (b, a),这样 ab 的值就互换了。

比如:

a = 1
b = 2
a, b = b, a
print(a, b)  # 输出 2 1

这里 a, b = b, a 背后其实是:

  • 先计算等号右边的表达式 (b, a),得到一个元组 (2, 1)
  • 然后按顺序解包赋值给左边的 ab

所以整个过程没有用到额外的临时变量,而且Python内部会确保这个操作是原子的,不用担心中间状态问题。

一句话总结:利用元组打包和解包的特性一步完成交换。

学一学编译和解释器的概念

dis 看看

Python 元组拆包,当 a, b = b, a 的时候,会把 b, a 看做一个可迭代对象,依次赋值给 a, b 组成的元组

用 dis 看一看汇编就懂了

个人觉得这只不过是一种语法糖,虽然没写中间变量底层说不定用了

如果是这么个问法,我觉得任何语言都可以不用变量交换两个值。

unpacking,也就是多个产量负值时序列的拆包。简易写法

虽然没有用临时变量,但是用了栈。

同意一楼的说法

dis 是??

你没看到不代表不存在

背后相当于做了:(伪代码)

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

和内存地址没什么关系。各种语言不同的写法最后都会被编译成类似的机器代码。

感谢各位大神,原来答案不只是拆包。现在优化了之后,在 2、3 个值分配的时候是直接运用栈,在 3 个以上值分配的时候才是用了拆包的原理。
详细答案在 11 楼哥们的链接里: https://stackoverflow.com/questions/21047524/how-does-swapping-of-members-in-the-python-tuples-a-b-b-a-work-internally

都用 python 了就别想着"内存地址"了

不爱思考的新手

只是语法糖而已,如果有一种新的语言,甚至可以这样表示交换两个变量:
a<->b

元组的自动组包与自动解包

python 是个栈机,push pop 一波搞定

其实没有用中间变量吧。

只不过 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

想知道只用加减法怎么实现,不用临时变量交换两个值

百度一下有很多

感激感激

a = a + b
b = a - b
a = a - b

#22 多谢科普

当时脑抽,看了半天没想出来,谢谢

回到顶部