一、生成器
''' 1 什么是生成器?(概念很重要) 在函数内但凡出现yield关键字,再调用函数就不会执行函数体代码,会返回值一个值,该值称之为生成器 生成器本质就是迭代器 2、为什么要有生成器? 生成器是一种自定义迭代器的方式(迭代器就是一种取值的方式) 3、如何用生成器 ''' def func(): print('first1') print('first2') print('first3') yield 1 #暂停 print('second1') print('second2') print('second3') yield 2 #暂停 print('third') yield 3 #暂停 print('fourth') g=func() #调用函数,遇到yield就不会执行函数体代码,会返回一个值,该值称之为生成器 # print(g) #<generator object func at 0x0000022593BA8360> # print(g.__iter__().__iter__().__iter__() is g) #True 生成器调用__iter__()方法得到得结果任然是迭代器本身 # res1=next(g) #调用next,拿到一个值得返回值,打印即可以看到结果 # print('第一次的返回值:',res1) # # # print('='*100) # res2=next(g) #next第二次接着上一次暂停的yield的往下进行取值,遇到yield在暂停,并拿到一个返回的结果 # print('第二次的返回值:',res2) #打印返回的结果 # # print('='*100) # res3=next(g) #next第三次接着上一次暂停的yield的往下进行取值,遇到yield在暂停,并拿到一个返回的结果 # print('第三次的返回值:',res3) #打印返回的结果 # # print('='*100) # res4=next(g) #迭代器中值已经被取干净,所以再去会报错,StopIteration,告诉你再next已经没有值了 # print('第四次的返回值:',res4) # for item in g: #g=iter(g) #item=next(g) #用一个for循环实现上面同样的结果,for的底层原理 # print(item) # i=range(1,1000) # for item in range(1,10000000000000000000000000000000): #先产生一个生成器,在每次next出一个结果出来 # print(item) # 自定义一个生成器(即迭代器) def my_range(start,stop,step=1): while start < stop: yield start # 暂停 start+=step g=my_range(1,5,2) #1 3 # print(g) #<generator object my_range at 0x000001BB86F583B8> 产生了一个生成器即迭代器可以执行next方法,将其中的值进行取出来 # print(next(g)) # 1 # print(next(g)) # 3 # print(next(g)) #迭代器中的值已经取干净了,所以再取就会报错StopIteration # print(next(g)) # print(next(g)) # print(next(g)) # print(next(g)) # for item in g: # print(item) #1、3 #总结yield的功能 #1、提供一种自定义迭代器的方式 #2、yield可以暂停住函数,返回值 #yield VS return #相同点:都是用在函数内,都可以返回值,没有类型限制,没有个数限制 #不同点:return只能返回一次值,yield可以返回多次值 # 了解知识 # yield 值 # x=yield #可以通过send给yield传值 # x= yield 值 #可以给yield传值,同时拿到一个返回值 # def dog(name): # food_list=[] # print('狗哥 %s 准备开吃' %name) # while True: # food=yield food_list#暂停 food=yield='一桶泔水' # print('狗哥[%s]吃了<%s>' %(name,food)) # food_list.append(food) # alex_dog=dog('alex') #先自定义了一个生成器<generator object dog at 0x000001EFEC4A8360> # res1=next(alex_dog) # 初始化,即让狗准备好 #生成器next一次取出一个值,遇到yield暂定,并拿到一个返回值 # print(res1) #此时yield的返回值是一个空[] # next(alex_dog) # 等同于alex_dog.send(None) #又next一次会基于上一次暂停的位置继续往后走,因返回值为空即为None,所以出现狗哥[alex]吃了<None>,直到再遇到yield暂停,并拿到一个返回值 # next(alex_dog) #狗哥[alex]吃了<None> # res2=alex_dog.send(('一泡翔','咖啡伴侣')) #yield会接收到send的值并赋值给food,并且send有next的意思会将yield后的返回值返回 # print(res2) #打印即可看到yield后的返回值 # # res3=alex_dog.send('一桶泔水') #yield会接收到send的值并赋值给food,并且send有next的意思会将yield后的返回值返回 # print(res3) #打印即可看到yield后的返回值
二、三元表达式
#三元表达式 # 条件成立时的返回值 if 条件 else 条件不成立时的返回值 # def max2(x,y): # if x > y: # return x # else: # return y # x=10 # y=20 # res=x if x > y else y #条件成立的时候返回x ,条件不成立的时候返回y,res结束返回值 # print(res) #打印返回值
三、列表+字典+集合生成式
# 列表生成式 # l=[item**2 for item in range(1,11)] #在列表中for循环拿到循环的结果放在for的左边当做列表中的元素 # print(l) # 列表生成式的应用: # 将列表中的人名末尾加上SB # 方法一: # names=['alex','wxx','lxx'] # l=[] # for name in names: # l.append(name + 'SB') # names=l # 方法二:列表生成式法 # names=[name+'SB' for name in names] #使用for循环,将循环的值(值可以做一系列的变换)放在for的左边,当做列表的元素, # print(names) # 将列表中出了egon以外人名加上SB # 方法一: # 筛选判断过滤掉egon # names=['alex','wxx','egon','lxx','zhangmingyan'] # l=[] # for name in names: # if name != 'egon': #过滤掉egon # l.append(name + 'SB') #字符串的拼接 # names=l #将新列表赋值给原列表 # 方法二:列表生成式法,加上判断条件 # names=[name+'SB' for name in names if name != 'egon'] # print(names) # 列表生成式+判断 # l=[item**2 for item in range(1,5) if item > 2] # print(l) # 列表生成式 # names=['egon','alex_sb','wupeiqi','yuanhao'] # names=[name.upper() for name in names] # print(names) # 列表生成式+判断 # names=['egon','alex_sb','wupeiqi','yuanhao'] # nums=[len(name) for name in names if not name.endswith('sb')] # print(nums) #字典生成式 # s1='hello' # l1=[1,2,3,4,5] # # res=zip(s1,l1) #拉链式函数,将每一个值一一对应起来 # print(res) #<zip object at 0x0000014890E82408> # print(list(res)) #[('h', 1), ('e', 2), ('l', 3), ('l', 4), ('o', 5)] # keys=['name','age','sex'] # values=['egon',18,'male'] # # res=zip(keys,values) # print(list(res)) #[('name', 'egon'), ('age', 18), ('sex', 'male')] # print(list(res)) #[],list底层原理就是一个for循环,迭代器中的值在第一次list已经取干净了,所以第二次在取已经为空 # d={} # for k,v in zip(keys,values):#小元组的解包 # d[k]=v #字典存key:value的方法 # print(d) #{'name': 'egon', 'age': 18, 'sex': 'male'} # 字典生成式:在大括号内使用for循环,将循环的得到的值(值可以自定义格式)放到for的左边,当做大括号内的元素, # keys=['name','age','sex'] # values=['egon',18,'male'] # d={k:v for k,v in zip(keys,values)} #for左边的值自定义为key:value的形式 # print(d) #{'name': 'egon', 'age': 18, 'sex': 'male'} # info={'name': 'egon', 'age': 18, 'sex': 'male'} # keys=info.keys() #keys是一个可迭代对象 # print(keys) #dict_keys(['name', 'age', 'sex']) # iter_keys=keys.__iter__() # values=info.values() #values也是一个可迭代对象 # print(values) #dict_values(['egon', 18, 'male']) # # d={k:v for k,v in zip(keys,values)} # print(d) #{'name': 'egon', 'age': 18, 'sex': 'male'} # 集合生成式:(就是字典生成式的衍生) # s={i for i in range(10)} # print(s,type(s)) # 生成器表达式 # g=(i for i in range(10)) #g生成器有__next__方法,即g就是迭代器 # print(g) #<generator object <genexpr> at 0x000001BDB32E8308> # # print(next(g)) # 0 每next一次,取到一个值 # print(next(g)) # 1 # nums=[11,22,33,44,55] # print(max(nums)) #执行iter方法得到迭代器,在执行next方法取到一个值,在next一次比较两者大小,取到最大值,再next一次取到一个值与之比较,一次类推取到最大值 # with open('a.txt',encoding='utf-8') as f: # nums=(len(line) for line in f) #小括号得到的是生成器 # print(nums) #<generator object <genexpr> at 0x000001F2CA368308> # print(max(nums)) #21 ,文本文件中某一行最长字符的长度 # print(max(nums)) # print(max(nums)) # l=['egg%s' %i for i in range(100)] #中括号拿到的是一筐鸡蛋 # print(l) #直接给了100个鸡蛋,但是篮子大小是有限的 # # # g=('egg%s' %i for i in range(1000000000000)) #小括号拿到的是一只可以无限制下蛋的鸡,你要一个就下一个 # print(g) #生成器:<generator object <genexpr> at 0x0000027FEDF58308> # print(next(g)) #egg0 # print(next(g)) #egg1