当我在一行上写东西时,区别在于,
和两行。显然我不明白其中的区别,因为我虽然下面的两个函数应该返回相同的。
def fibi(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
print(fibi(6))
> 8 # expected result (Fibonacci)
但是
def fibi(n):
a, b = 0, 1
for i in range(n):
a = b
b = a + b
return a
print(fibi(6))
> 32
答案 0 :(得分:13)
这是因为Python的元组解包。在第一个中,Python收集右侧的值,使它们成为元组,然后将元组的值分别分配给左侧的名称。所以,如果a == 1且b == 2:
a, b = b, a + b
=> a, b = (2, 3)
=> a = 2, b = 3
但是在第二个例子中,它是正常的分配:
a = b
=> a = 2
b = a + b
=> b = 4
答案 1 :(得分:2)
找到
的替代品a, b = b, a + b
您必须意识到此分配是“一步一步”执行的。
所以它的等价物是
old_a = a
a = b
b = old_a + b # note the old_a here, as a has been replaced in the meanwhile.
演示:
def fibi(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
def fibi2(n):
a, b = 0, 1
for i in range(n):
old_a = a
a = b
b = old_a + b
return a
>>> fibi(0)
0
>>> fibi(1)
1
>>> fibi(2)
1
>>> fibi(3)
2
>>> fibi(4)
3
>>> fibi(5)
5
>>> fibi(6)
8
>>> fibi(7)
13
>>>
>>>
>>>
>>> fibi2(0)
0
>>> fibi2(1)
1
>>> fibi2(2)
1
>>> fibi2(3)
2
>>> fibi2(4)
3
>>> fibi2(5)
5
>>> fibi2(6)
8
>>> fibi2(7)
答案 2 :(得分:1)
你的不同之处在于:
1)
>>> a, b = 0, 1
>>> a, b = b, a+b
>>> a
1
>>> b
1
VS
2)
>>> a, b = 0, 1
>>> a = b
>>> b = a+b
>>> a
1
>>> b
2
在第一种情况下,a = 1
和b = 0 + 1
在变量的值发生变化之前。您基本上是说“在给定状态X下使用(a,b)
,将(a,b)
设置为值(0,1)
。”
了解这些事情的不同之处的一个好方法是使用disassembly模块(按照链接查看代码含义):
>>> from dis import dis
>>> a, b = 0, 1
>>> dis('a, b = b, a+b')
1 0 LOAD_NAME 0 (b)
3 LOAD_NAME 1 (a)
6 LOAD_NAME 0 (b)
9 BINARY_ADD
10 ROT_TWO
11 STORE_NAME 1 (a)
14 STORE_NAME 0 (b)
17 LOAD_CONST 0 (None)
20 RETURN_VALUE
>>> a, b = 0, 1
>>> dis('a = b; b = a+b')
1 0 LOAD_NAME 0 (b)
3 STORE_NAME 1 (a)
6 LOAD_NAME 1 (a)
9 LOAD_NAME 0 (b)
12 BINARY_ADD
13 STORE_NAME 0 (b)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
答案 3 :(得分:0)
不同之处在于,在第二个示例中,您在引用a
之前将b
设置为a
。第二个示例中的值将关闭。这是一个例子:
a = 5
b = 6
实施例1,:
a, b = b, a+b // a = 6 and b = 11
例2:
a = b // a = 6
b = a + b // b = 6+6 or 12
第一个例子是正确的
答案 4 :(得分:0)
在第一种情况下,命令
a, b = b, a + b;
将首先执行总和a + b
,然后执行分配。在这种情况下,b总是包含1.这解释了为什么最终结果是6,因为你要加6次。
您发布的第二个代码是正确的。
答案 5 :(得分:0)
Raymond Hettinger的完美解释可以在这个PyCon 2013视频中找到,时间是33:13到38:17:
https://www.youtube.com/watch?v=OSGv2VnC0go
引用他的演讲:
- 不要低估同时更新状态变量的优势
- 消除了由于无序更新导致的整类错误