在python赋值过程中,对单个变量的赋值,在所有语言中都是通用的,如果是对两个变量同时进行赋值,这个时候,就会出现一点点小的差异。例如在下面的一两行代码中。
a , b = b , a+b
这是同时对两个变量进行赋值,假如当前a=1,b=2,运算之后,a=2,b=3,实际上的运算过程是,先将当前的b和a+b放进一个元祖中,temp = (b,a+b),然后再对a和b进行赋值,a=temp[0],b=temp[1]。
这种运算赋值,最常见的一个算法,就是斐波那契,斐波那契的结果就是当前数的结果,是前两个数之和。正好用到了这种赋值方式。代码如下:
def fib(number):
a = 0
b = 1
n = 1
if number == n:
return a
elif number == b:
return b
else:
while n < number:
a , b = b , a+b
n +=1
return b number_list = [ fib(i) for i in range(1,10)]
print(number_list)
首先要定义两个初始的变量,也就是第1个数为0,第2个数为1,后面的数都是根据这个数字来加。下面还是用了一个列表生产式,将斐波那契的结果放入到该列表生产式中。世界上得到的是一个列表。
虽然这个列表的生成方式比较简单,对于内存来数,还是一次性的生成,然后放入到内存中。如果生产的数较大,也会占用大量的内存,所以这个时候就有一个生成器的东西。生成器是一个内存对象,通过每次生成一个数字,放入内存中,同时覆盖掉之前生成的数字,保证内存中只有一个数字,从而减少内存的占用。
列表生产式和生成器都可以遍历整个列表中的数字,只不过生成器只能够向下取一个,但是生成式可以通过索引进行取值。
修改一下上面的代码,形成一个生成器,一个对象。
def fib(number):
a = 0
b = 1
n = 1
if number == n:
return a
elif number == b:
return b
else:
while n < number:
a , b = b , a+b
n +=1
return b number_list = (fib(i) for i in range(1,100))
print(number_list)
print(number_list.__next__())
print(next(number_list))
生成式和生成器之间的区别,就是一个是列表,一个是内存对象,[]与()的区别。通过调用next方法来取值。
实际上,上述代码只是对斐波那契的结果,进行了生成器的操作,在计算斐波那契的时候,还是需要计算值。能不能想点办法,在计算的时候,不计算那么多值。也就是做一个斐波那契的类表生成器。这个时候用到了yield。生成器对象的关键。
def fib(number):
a ,b ,n = 0 , 1 , 1
if number == n:
return a
elif number == b:
return b
else:
while n < number:
yield b
a , b = b , a+b
n +=1
return b number = fib(10)
# print(number.__next__())
for i in number:
print(i)
使用了yield之后,这个斐波那契函数创建的变量,就变成了一个生成器。生成器就只能通过循环或者next方法来取值。不能进行切片了。
当使用yield时,调用next方法,程序会回到yield,然后开始执行下一个操作,同时将yield后面的值返回。