被一个及其简单的 a,b = b,a 问倒了,在线感性求助!!!

2018-07-22 19:42:56 +08:00
 firejoke

今天被问到
a,b = b,a 是如何实现的
轻蔑的告诉对方这是因为交换了内存地址啊
然而我自己多事,要给别人演示

a = 1
b = 2
id(a)

4304968096

id(b)

4304968064

a,b = b,a
id(a)

4304968064

id(b)

4304968096

目前为止没有任何问题
然后我又解释到:
因为实际上它是这样运行的啊

(a,b)=(b,a)
a

1

b

2

你看,这是生成了两个新的元组在参与运算

id((a,b)),id((b,a))

(4356155464, 4356155464)

诶?! 你等等

(a,b) is (b,a)

False

诶?! 诶?! 你再等等(莫非 tuple 太特殊了)

id([a,b]),id([b,a])

(4356157384, 4356157384)

我 c?! 不行!

id([a,b][0]),id([b,a][0])

(4304968096, 4304968064)

是不同的 id 啊,这个......
那个,你等等啊

各位 V 大! 在线求助啊!!!

4521 次点击
所在节点    Python
22 条回复
dongdawang
2018-07-24 11:59:24 +08:00
@lilydjwg
三个变量的交换
import dis
dis.dis("a=1;b=2;c=3;a,c,b=c,b,a")

1 0 LOAD_CONST 0 (1)
3 STORE_NAME 0 (a)
6 LOAD_CONST 1 (2)
9 STORE_NAME 1 (b)
12 LOAD_CONST 2 (3)
15 STORE_NAME 2 (c)
18 LOAD_NAME 2 (c)
21 LOAD_NAME 1 (b)
24 LOAD_NAME 0 (a)
27 ROT_THREE
28 ROT_TWO
29 STORE_NAME 0 (a)
32 STORE_NAME 2 (c)
35 STORE_NAME 1 (b)
38 LOAD_CONST 3 (None)
41 RETURN_VALUE
#三个变量的交换使用 ROT_THREE。

但是发现
无论是
dis.dis("a=1;b=2;(a,b)=(b,a)")
还是
dis.dis("a=1;b=2;a,b=b,a")
字节码命令都是
1 0 LOAD_CONST 0 (1)
3 STORE_NAME 0 (a)
6 LOAD_CONST 1 (2)
9 STORE_NAME 1 (b)
12 LOAD_NAME 1 (b)
15 LOAD_NAME 0 (a)
18 ROT_TWO
19 STORE_NAME 0 (a)
22 STORE_NAME 1 (b)
25 LOAD_CONST 2 (None)
28 RETURN_VALUE

也就是说无论几个元素交换,都是构建 tuple 来实现的?
lilydjwg
2018-07-24 22:04:25 +08:00
@dongdawang #21 并没有构建 tuple 啊。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/473116

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX