Python中为什么(a, b = b, a + b)和 (a = b, b = a+b)不相同

以Fibonacci数列为例

所谓的Fibonacci数列(也称为“兔子数列”)是指这样一串数字:1, 1, 2, 3, 5, 8, 13, 14, …

实际上这个数列符合这样的规律:an = an-1 + an-2

如果我们定义一个生成Fibonacci数列的类Fibs
代码如下:

>>> class Fibs:
	def __init__(self):
		self.a = 0
		self.b = 1
	def __iter__(self):
		return self
	def __next__(self):
		self.a, self.b = self.b, self.a+self.b
		return self.a

实例化对象之后,打印20以内的数列
——一定要设置范围哈,不然不会停

>>> fibs = Fibs()
>>> for each in fibs:
	if each < 20:
		print(each, end = ' ')
	else:
		break

	
1 1 2 3 5 8 13 

我们注意到,在类中有一段奇怪的赋值语句:

self.a, self.b = self.b, self.a+self.b

如果你认为这个赋值语句相当于:

>>> self.a = self.b
>>> self.b = self.a + self.b

程序变为:

>>> class Fibs:
	def __init__(self):
		self.a = 0
		self.b = 1
	def __iter__(self):
		return self
	def __next__(self):
		self.a = self.b
		self.b = self.a + self.b
		return self.a

	
>>> fibs = Fibs()
>>> for each in fibs:
	if each < 20:
		print(each, end = ' ')
	else:
		break

	
1 2 4 8 16 

可以看到,运行出来的结果很怪异,反正不是兔子数列!

Python的多变量赋值

要理解上面的赋值操作,需要了解一下Python的复制规则:

self.a, self.b = self.b, self.a+self.b

1 Python赋值是将右边的值赋给左边
2 如果等号右边有运算,那么就先运算之后才赋值

也就是说:
1 先计算等号右边的运算self.a + self.b = 0+1 = 1
2 然后将self.b = 1, 赋值给self.a
3 再将计算好的self.a + self.b = 0+1 = 1 ,赋值给self.b

那要怎么改?

增加一个中间变量就好了!

>>> class Fibs:
	def __init__(self):
		self.a = 0
		self.b = 1
	def __iter__(self):
		return self
	def __next__(self):
		temp = self.a + self.b
		self.a = self.b
		self.b = temp
		return self.a

	
>>> fibs = Fibs()
>>> for each in fibs:
	if each < 20:
		print(each)
	else:
		break

	
1
1
2
3
5
8
13

无限循环很可怕,怎么修改类函数,让计算可以停下来呢?

直接看代码:

class Fibs:
	def __init__(self, n = 10):
		self.a = 0
		self.b = 1
		self.n = n
	def __iter__(self):
		return self
	def __next__(self):
		
		self.a, self.b = self.b, self.a + self.b
		if self.a > self.n:
			raise StopIteration
		return self.a

__iter__是一个迭代器方法,用StopIteration可以让迭代停下来。
在实例化对象的时候,也是可以通过输入n的值来控制迭代的深度。

开心!优化了呢!

猜你喜欢

转载自blog.csdn.net/Haoyu_xie/article/details/106229539
B
a^b
A/B
A*B
A+B