生成器
1.啥是生成器
生成器也是一种迭代器,但是它有迭代器的其他功能。那它有什么特殊的功能呢?我们不妨举个例子。
如果我们要产生一个很大的列表,但是又不全拿出来,这时候列表所有数据都在内存中,大量数据的话将会非常耗内存。这时候如果列表元素按照某种算法推算出来,我们需要时,就提出来,这样就会省去大量的空间。
2.咋判断它是生成器
判断生成器,也就是看生成器的标志:yield 。 有了它就就变成了生成器
3.生成器何时产生
我们来举个例子看一下。
# 生成器
def num(): # 斐波那契数列
a, b = 0,1
for i in range(5):
yield b
a,b = b,a+b
print(num) # 在这里显示是函数
c = num()
print(type(c)) # 在这里显示的就是生成器了
输出结果:
<function num at 0x00000237220160D0> <class 'generator'>
一个是函数,一个是生成器。当把函数赋给一个值的时候,它就成为了生成器。
4.生成器产生的方法
- 第一种方法比较简单,但是它不正宗
b = (x*2 for x in range(10))
print(type(b))
这种方法是根据列表推导式来产生的生成器。因为已经是生成器了,所以就可以用 next(b)的方法来执行,获取其中第一个元素。
也可以用for循环来取出其中的元素。
b = (x*2 for x in range(10))
for num in b:
print(num)
输出结果:
0 2 4 6 8 10 12 14 16 18
- 第二种方法:我们举一个大家都在用的例子说明第二种方法
def num(): # 斐波那契数列
a, b = 0,1
for i in range(5):
yield b
a,b = b,a+b
c = num()
next(c)
for i in c:
print(i)
用生成器写一个斐波那契数列。输出结果是:输出一个值,不断使用next(c)方法,直到输出5再next(c),会报出StopIteration错误。如果想要不报错的,那就使用for循环,这样就不会出错。就是我上面注释掉的。
列表推导法
列表推到式属于生成器
举个例子:
a = [x for x in range(10)]
print(a)
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
再拿这个例子升级一下:
a = [x**2 for x in range(10)]
print(a)
结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
解释:
说明前面x是后面那个x的结果,我们同时也可以对后面的数进行操作
进阶例子:
vec = [(1,2,3), (4,5,6), (7,8,9)]
a = [x for List in vec for x in List]
print(a)
结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
解释:
for循环后面还可以添加for循环,同时里面的可以是元组、列表。
再进阶例子:
print([x for x in range(1,8) if x%2 == 0])
结果:[2, 4, 6]
解释:说明还可以对for循环得到的子项目进行判断以及其他操作
关于生成器我自己觉得我还理解的不够,这篇文章我还是会补充的,希望到时候能够有了更深的理解。