始终想不明白 a, b = b, a + b 到底是怎么工作的?

2018-05-18 17:39:35 +08:00
 Eyon

如下例:

class Fib(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a,b

f = Fib()

print(f[0])

输出为什么是(1,1),而不是( 1,2 )?后面那个 1 到底是怎么产生的?

4188 次点击
所在节点    Python
15 条回复
kenorizon
2018-05-18 17:42:38 +08:00
list(range(0)) == []
mofe
2018-05-18 17:42:47 +08:00
for x in range(0) ,所以后面的赋值语句没有跑。。。
IanPeverell
2018-05-18 17:43:02 +08:00
a, b = b, a+b
完成的工作相当于
c = a
a = b
b = c+b
wellsc
2018-05-18 17:43:22 +08:00
后面那个 1 难道不是你自己赋值的?
```python
a, b = 1, 1
```

range(0) 的结果就是空列表好嘛?根本没有跑进循环体啊

``` python
>>> for i in range(0):
... print('进来了吗')
...
>>> print(range(0))
[]
>>>
```
Eyon
2018-05-18 17:57:44 +08:00
@wellsc
@mofe

0 基础初学 python,可能有些理解欠缺,照你们这么说,我对 for 循环的理解有误?

拿 for x in range(3)举例,x 会分别赋值 0,1,2,也就是它会运行 3 次。
第一次:
a,b = b,a+b ---->(1,2)
第二次:
a,b = b,a+b ---->(2,3)
第三次:
a,b = b,a+b ---->(3,5)

那么,f[0]不是取第一次运算后的结果么?
gnaggnoyil
2018-05-18 17:59:24 +08:00
@Eyon `f[0]`等于`f.__getitem__(0)`...
mofe
2018-05-18 18:03:07 +08:00
@Eyon 额,我们来数个数

range(3) 会赋值 0 1 2
range(2) 会赋值 0 1
range(1) 会赋值 0
range(0) 呢?
Eyon
2018-05-18 18:06:11 +08:00
@mofe

[/捂脸][/捂脸][/捂脸],恍然大悟!

f[0]不是取第一次运算的结果,而是取 n=0 时的结果,这么简单的逻辑,思考了两个下午都没思考透哈哈哈。
Nostalgiaaaa
2018-05-18 18:56:56 +08:00
a, b = b, a+b
这个其实是元组赋值了,python 会自动把右边这种用逗号分开的格式作为元组, 例如:
>>> a = 1, 2
>>> type(a)
<class 'tuple'>
>>> c, d = a
>>> c, d
(1, 2)
也就是这个语句大概上就是个语法糖, 右边是多个值赋值, 左边是元组。
F1024
2018-05-18 19:38:18 +08:00
你至少要给 n 赋个值吧
PythonAnswer
2018-05-18 19:42:18 +08:00
Fib 一般有个 if 吧
OldPanda
2018-05-19 05:29:00 +08:00
把这个 Fib 类转换成字节码可以看到,for 循环内部是这个样子的
5 22 LOAD_FAST 3 (b)
24 LOAD_FAST 2 (a)
26 LOAD_FAST 3 (b)
28 BINARY_ADD
30 ROT_TWO
32 STORE_FAST 2 (a)
34 STORE_FAST 3 (b)
36 JUMP_ABSOLUTE 18
>> 38 POP_BLOCK

可以看到按照 b, a, b 的顺序压栈,然后对栈顶的两个元素进行相加(即 a + b ),然后分别存到 b, a (这里故意写反,因为中间有一个 ROT_TWO 操作)。所以说白了,Python 先把 b, a + b 的值分别准备好,再依次交给原有的 a, b。
pmispig
2018-05-19 15:11:25 +08:00
这样写的是傻逼
opengps
2018-05-19 17:58:51 +08:00
true 可以用 1 表示
AlisaDestiny
2018-05-20 16:36:21 +08:00
for x in range(3) 你知道是运行 3 次,那 for x in range(0) 是运行 1 次?是你犯糊了还是我犯糊了。

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

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

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

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

© 2021 V2EX