(本文仅作为学习记录)
生成器和推导式
01. 昨日内容
02. 生成器
03. 推导式
01. 昨日内容
# 迭代器: # 迭代器有iter方法 next方法就是迭代器 # 递归: # 1.自己调用自己 # 2.明确的结束条件 # 递归的最大深度 官方 1000 实际测试:998/997 # import sys # sys.setrecursionlimit(100000) # # 修改最大深度 # 递归的效率不高,尾递归的效率和for循环是一样 # 递归的应用场景: 在不明确循环次数的时候,就可以使用递归 # for循环的本质: # # li =[1,23,3] # # iter(li) == li.__iter__() # li = li.__iter__() # while True: # try: # print(li.__next__()) # except StopIteration: # break # 迭代器的特性: # 1.惰性机制 # 2.不能逆行,只能从上向下 # 3.一次性的 # 4.省内存 # 函数名的使用: # 1.当做值赋值给变量 # 2.可以当做返回值被返回 # 3.可以当做容器里的元素 # 4.可以当做参数传递 #闭包: # 1.有一个嵌套函数 # 2.在嵌套函数内部的函数使用非全局变量 # 优点: 安全 装饰器需要 # 缺点: 容易造成内存泄漏 # 怎么查看??? # 函数名.__closure__
02. 生成器
# 1.生成器的本质就是迭代器 # 2.通过函数变成一个生成器 # def func(): # print(1) # yield 5 # 我的函数走到这了 # print(2) # yield 9 # 我的函数走到这了 # # g = func() # 生成一个生成器 # print(g.__next__()) # print(g.__next__()) # print(list(range(10000))) # def func(): # print(1) # # return 5 # yield 5 # print(func().__next__()) # 这样生成一个生成器 # print(func().__next__()) # 这样生成一个生成器 # print(func().__next__()) # 这样生成一个生成器 # print(func().__next__()) # 这样生成一个生成器 # 函数体存的是不是代码 # 1.语法分析 # 2.语义分析 # 3.词法分析 # python2 next() iter() # python3 next() __next__() iter() __iter__() # 大批量的数据的时候首先要想到生成器 # def func(): # print(1) # yield 5 # 我的函数走到这了 # print(2) # yield 9 # 我的函数走到这了 # # g = func() # 生成一个生成器 # print(g.__next__()) # print(g.__next__()) # 碰到return就结束函数 # 碰到yield不结束就挂起 # 生成器的好处,非常节省内存 # def func(): # print(1) # a = yield 2 # 1.挂起 2.返回值 3.接受值 # print(a) # '123' # print(3) # b = yield 4 # print(b) #'234' # c = yield 9 # # g = func() # # print(g.__next__()) #1 2 g.send(None) # print(g.send('123')) # send = next+传值 # print(g.send('234')) # send = next+传值 # # 第一次调用生成器的时候使用send里边的值必须是None # def func(): # yield 1 # yield 2 # # g = func() # ret = g.__next__() # print(ret+4) # print(g.__next__()) # def func(): # li = [1,2,3,4] # # yield li # yield from li # # ret = func() # 把生成器的地址给了ret # print('is ret',ret.__next__()) # # 执行ret这个变量的指向的生成器地址 # print('is ret',ret) # # 在全局空间找到一个变量叫做ret的,打印它的值 值就是生成器的地址 # def func(): # li = [1,2,3,4] # l2 = [5,6,7,8] # # yield from li # # yield from l2 # for i in li: # yield i # # for em in l2: # yield em # # ret = func() # 把生成器的地址给了ret # print('is ret',ret.__next__()) # print('is ret',ret.__next__()) # print('is ret',ret.__next__()) # print('is ret',ret.__next__()) # print('is ret',ret.__next__()) # 总结: # 1.生成器的本质就是一个迭代器 # 2.生成器一定是一个迭代器,迭代器不一定是一个生成器 # 3.生成器是可以让程序员自己定义的一个迭代器 # 4.生成器的好处,节省内存空间 # 5.生成器的特性 一次性的,惰性机制,从上向下 # 6.send相当于 next+传值,第一次触生成器的时候,如果使用send(None) # 值必须是None,一般我建议你们使用__next__ # 7. python2 iter() next() # python3 iter() next() __next__() __iter__() # 8.yield from 将可迭代对象元素逐个返回 # def func(): # with open('t','r',encoding='utf-8')as f: # for i in f: # i = i.strip('\r\n') # yield i # # g = func() # for i in range(10): # print(g.__next__())
03. 推导式
# 列表推导式 # li = [] # for i in range(10): # li.append(i) # print(li) # print([i for i in range(10)]) # [结果 语法] #容器 # li = [] # for i in range(10): # if i%2 == 1: # li.append(i) # print(li) # print([i for i in range(10) if i%2 == 0]) # 过滤(筛选) # li = [] # for i in range(10): # for em in range(3): # li.append(em) # print(li) # print([j for i in range(10) for em in range(3) for j in range(5)]) # 集合推导式 # s = {i for i in range(10)} # print(s) # {结果 语法} 容器 # 字典推导式: # print({i:i+1 for i in range(10)}) # print(type({1,2,32,4})) # g = (i for i in range(10)) # {'1':1,'2':2} # {'1','2'} # {1:2,2:3,3:4} # {'美女':1999,1999:2} # 推导式: # 1.列表 # 2.集合 # 3.字典 # 1.生成器推导式
04. 总结
# 1.生成器: # 总结: # 1.生成器的本质就是一个迭代器 # 2.生成器一定是一个迭代器,迭代器不一定是一个生成器 # 3.生成器是可以让程序员自己定义的一个迭代器 # 4.生成器的好处,节省内存空间 # 5.生成器的特性 一次性的,惰性机制,从上向下 # 6.send相当于 next+传值,第一次触生成器的时候,如果使用send(None) # 值必须是None,一般我建议你们使用__next__ # 7. python2 iter() next() # python3 iter() next() __next__() __iter__() # 8.yield from 将可迭代对象元素逐个返回 # 2.推导式: # 总结: # 列表 # 集合 {1,2,3} # 字典 {1:2,2:4} # 看着像元组的其实是一个 生成器推导式 # 1.外部需要容器包一下,里边第一个位置 结果 剩下位置都是语句 # 2.推导式 -- 面试 实现小的需求时可以使用推导式,推导式节省代码 # 3.推导式不要写太长,可读性差.