python_生成器
一、列表生成式:
列表生成式即python内置的非常简单且强大的生成list的生成式。
range(1,10)方法可以生成一个简单的list,
1 l = [] 2 3 for i in range(1,10): 4 l.append(i) 5 6 print(l) 7 >>>[1, 2, 3, 4, 5, 6, 7, 8, 9] 8 9 10 l = [] 11 12 for i in range(1,10): 13 l.append(i*i) 14 15 print(l) 16 >>>[1, 4, 9, 16, 25, 36, 49, 64, 81]
这样生成一个list有些许累赘,列表生成式就是为了简化这一过程:
l = [i for i in range(1,10)] print(l) >>>[1, 2, 3, 4, 5, 6, 7, 8, 9] L = [i * i for i in range(1,10)] print(L) >>>[1, 4, 9, 16, 25, 36, 49, 64, 81]
for后边还可以加if判断,过滤出列表中所有的奇数:
1 L = [i * i for i in range(1,10) if i % 2 != 0] 2 print(L) 3 4 >>>[1, 9, 25, 49, 81]
还可以两个for循环一起使用:
l = [ x * y for x in range(1,5) for y in range(6,10)] print(l) >>>[6, 7, 8, 9, 12, 14, 16, 18, 18, 21, 24, 27, 24, 28, 32, 36]
二、生成器(generator):
生成器是一种只有在调用时才会开始计算生成相应的数据,没调用时内存中只存储相关数据的计算方式和当前数据的相关位置。
生成器可以大大节省我的内存空间。
创建生成器的方法有很多种,方法一:只需要把列表生成式的“[ ]”改成“( )”即可
1 l = [i for i in range(10)] 2 print(l) 3 4 >>>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 5 6 g = (i for i in range(10)) 7 print(g) 8 9 >>><generator object <genexpr> at 0x000001DBE98C9888>
生成器输出的是可迭代的内存对象,可以理解为计算数据的方法。那么如何输出生成器中的数据呢 ?
使用 next() 方法可以一个个的输出数据:
g = (i for i in range(10)) print(g) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) >>><generator object <genexpr> at 0x000001C1102D9888> 0 1 2 3 4
next()方法会把生成器中的数据一个个输出,若是next()的次数大于range()值的次数,则报StopIteration的错误。
显然,用next()方法有点太low了,既然生成器是可迭代对象,那正确的取值方法是for循环:
1 g = (i for i in range(5)) 2 3 for i in g: 4 print(i) 5 6 >>>0 7 1 8 2 9 3 10 4
像这样的如此潇洒与直接。
方法二:yield
1 def yrd(): 2 print("this is 1") 3 yield 1 4 print("this is 2") 5 yield 5 6 print("this is 3") 7 yield 9 8 9 print(yrd()) 10 >>><generator object yrd at 0x00000204F9609888> 11 12 y=yrd() 13 next(y) 14 >>>this is 1 15 16 next(y) 17 >>>this is 2 18 19 next(y) 20 >>>this is 3
如果一个函数里有yield关键字,那个这个函数就不在是普通的函数了,而是摇身一变成为了生成器函数。
生成器函数与普通的函数执行顺序是不一样的,普通的函数遇到return,或是执行到结尾就返回,而迭代器函数是每次调用next()方法时遇到yield就返回,再次执行next()方法时从上次yield的位置继续执行。
同样,迭代器函数也可以使用for循环来取数据, for函数中其实也是封装的next()方法。当循环穷尽时for函数会自动获取报错退出。
1 def yrd(): 2 print("this is 1") 3 yield 1 4 print("this is 2") 5 yield 5 6 print("this is 3") 7 yield 9 8 9 for y in yrd(): 10 print(y) 11 12 >>> this is 1 13 1 14 this is 2 15 5 16 this is 3 17 9