Python函数之生成器
一、定义生成器
生成器当本质就是迭代器,在python中通过生成器函数和推导式来获取生成器
# 用过修改return成yield实现一个生成器 # 生成器当在执行的时候其结果为此生成器的内存地址 def f(): print("aaaa") yield 222 print(f()) # 使用生成器其就是其本质迭代器,直接使用迭代器方式就可使用生成器 def f(): print("aaaaa") yield 1111 x = f().__next__() #定义获取一个生成器,然后通过next获取函数 print(x)
yield和return本质相似,但其结果不同
yield:是分段来执行函数相当于计数位,当执行到yield后,yield同return一样也会返回一个值,但yield会挂起不会结束此函数。
return:是直接停止函数,return可以出现多次,但是执行遇到第一个return就会结束。
# 当数据量大的时候,我们不能一下全部把数据拿出,不仅浪费资源还会导致内存溢出 # 使用生成器是一个一个向下执行,调用一个就会按上次执行后继续执行,从而还能节省内存空间 def x(): for i in range(1000): yield i y = x() print(y.__next__()) print(y.__next__()) print(y.__next__()) print(y.__next__()) print(y.__next__())
def function(): for i in range(10): yield i y = function() while 1: try: print(y.__next__()) except StopIteration: break # send和next都是让生成器下次执行 # send将一个值赋给yield,当在第一次执行当时候不能直接使用send,但可以使用send(None) def x(): for i in range(3): a = yield i print(a) b = yield "00" print(b) y = x() print(y.__next__()) print(y.send("00001")) print(y.send("00002")) print(y.send("00003"))
二、yield form
# 使用生成器可以把一个可迭代的对象中的数据进行返回 def x(): li = [1, 2, 3, 4, 5, 6] yield from li y = x() for x in y: print(x) # 如果生成器中存在两个yield from 它会先执行完第一个yield才继续执行下一个 def x(): li = [1, 2, 3, 4, 5, 6] ls = [111,222,333,444] yield from li yield from ls y = x() for x in y: print(x)
三、列表推导式
# 列表推导式是通过一行来构建实现的列表 ls = [] for x in range(10): ls.append(x) print(ls) # 通过列表推导式来实现 ls = [x for x in range(10)] print(ls)
# 筛选模式 ls = [] for x in range(10): if x % 2 == 0: ls.append(x) print(ls) ls = [x for x in range(10) if x % 2 == 0] print(ls)
# 生成器推导式是将[]转成() # 其结果为一个生成器,使用for循环打印 x = (i for i in range(20)) for y in x: print(y) # 对一个范围内进行筛选 x = (i for i in range(20) if i % 2 == 1) for y in x: print(y) # 列表推导式:比较耗用内存资源,一次性加载得到的值是一个列表 # 生成器表达式:几乎不占用内存,当使用的时候才会分配使用内存,其结果是一个生成器
# 字典推导式也是将换成{}符号 li = [1,2,3,4,5] ls = ["a","b","c","d","e"] x = {li[i]:ls[i] for i in range(len(li))} print(x)
# 集合推导式是生成一个集合,无序不重复的 ls=[1-6,3,-7,9,11,-45,6-9] s={abs(i) for i in ls} #abs求绝对值 print(s)