Python之旅的第||天(生成器练习、往期知识回顾)
作者:互联网
详细练习了一下三元表达式,以及生成器函数,因为yield的加入,使很多函数更加的贴近实际情况。
要看的几篇东西还没去看,时间有点跟不上了啊。
#三元表达式 # name = input('>>>') # if name == 'alex': # print('sb') # else: # print('shuaige') #以上if段落可简写为 # print('sb') if name == 'alex' else print('shuaige') # 关于迭代器协议的自己理解,可迭代对象指的就是具有迭代器协议的对象 # 具有两个特点:1.具有__next__()方法,迭代是一个重复的过程,没迭代一次生成一个数据,每次迭代结果都是下次的初始值 # 能够通过报错停止迭代 注意:单纯的复制并不是迭代,对于字符串、列表、元组、字典、集合这些数据我们需要取出其中元素 # l = [1,'a','b'] # for i in l: # print(i) # 类似的元组、列表、字典其实是没有__next__方法的,那么他们首先是使用__iter__方法的 # f = l.__iter__() # print(f) #此时输出一个<method-wrapper '__iter__' of list object at 0x00000151A46A2E08> # 即为表示显示可迭代的对象 # 此时f便能够使用__next__方法,调用方法记得加上括号 # print(f.__next__()) #输出1 # print(f.__next__()) #输出'a' # print(f.__next__()) #输出'b' # print(f.__next__()) #上面三行依次分别显示了列表l的三个元素,最后一行报错 # 下面是for循环实际帮我们迭代时候做的事情,姑且用while来显示吧 # l = [1,'a','b'] # iter_test = l.__iter__() # while True: # try: #用于捕捉异常,即在执行__next__方法最后一个时,会产生异常,此时会终止循环 # k = iter_test.__next__() #iter_test.__next__()也可以写作next(iter_test) # #next是Python中自带的函数,同样可以通过执行next(对象)来实现操作 # print(k) # except StopIteration: # break #关于生成器,就是能够自动实现迭代器协议,能够直接使用__next__()方法的可迭代对象 #1.生成器函数,即返回值为yield的函数,(却别与return,yield可返回多个数值) #2.生成器表达式:三元表达式 #三元表达式 # name = input('>>>') # if name == 'alex': # print('sb') # else: # print('shuaige') #以上if段落可简写为 # print('sb') if name == 'alex' else print('shuaige') # 关于列表的解析 # 之前我们在生成一个列表时的操作(生鸡蛋的问题) # egg = [] # for i in range(1,11): # egg.append('鸡蛋%s'%i) # print(egg) #以上内容其实可以写作: # egg = ('鸡蛋%s'%i for i in range(1,11)) #这就是一个三元表达式,但是只使用了两元 # print(egg) #此时输出结果为:<generator object <genexpr> at 0x0000016B9FA55468> # #表示此时egg是一个可迭代的对象,那么此时egg就可以使用__next__()方法 # print(egg.__next__()) #输出:鸡蛋1 # print(next(egg)) #输出:鸡蛋2 #针对上面的三元表达式只用了两元,我可以在后面补充条件 # egg = ('鸡蛋%s'%i for i in range(1,11) if i > 5 ) #上面就是一个完整的三元表达式生成的生成器,可以直接调用__next__方法 # print(egg) #同样输出<generator object <genexpr> at 0x0000027F12495468>,表示可迭代对象 # print(egg.__next__()) #输出:鸡蛋6 # print(next(egg)) #输出:鸡蛋7 #关于生成器函数,即返回值是yield的函数 # yield的两个作用:1.相当于return返回函数的运行结果;2.保存函数当前运行状态\ # ,当__next__()方法执行的时候从上次yield处继续向下运行 #示例:还是关于生鸡蛋的问题 # def test(): # print('生了一个鸡蛋哦!') # yield 'egg_1' # print('生了两个鸡蛋哦') # yield 'egg_2' # print('生了三个鸡蛋哦') # yield 'egg_3' # test_list = test() # print(test_list) #此处输出结果为<generator object test at 0x000001CB17E55518> # #表示生成了一个迭代器,可以执行__next__方法 # print(test_list.__next__()) #此处的生成结果:生了一个鸡蛋哦!\n egg_1 # #表示函数只运行了两行,在第一个yield处停止 # print(test_list.__next__()) #此处的生成结果:生了两个鸡蛋哦!\n egg_2 # # 表示函数此时从上一个yield处的后面开始运行,并在第二个yield处停止运行 # print(test_list.__next__()) #第三个就不多说了 #以上可以表明,yield在函数中不光可以返回值,同时还可以记住当前函数运行状态\ #只有__next__()方法触发后才会继续运行,运行范围是上一个yield之后开始,到遇到下一个yield处运行结束。 #上面这个函数只能看出yield的执行过程,对于他的作用还是不够明显 #引入:包子铺生产包子再卖包子的过程 #首先是在我不知道yield的时候 # def product_baozi(): #生产包子方法,生产了100个包子 # res = [] # for i in range(1,101): # res.append('做好了第%s个包子'%i) # print(res) # def chibaozi(): # res_1 = [] # for i in range(1,101): # res_1.append('来的第%s个人吃包子'%i) # print(res_1) # # product_baozi() # chibaozi() #而在实际生产过程中,包子在生产后就会被卖掉,而不是等所有包子全部做好了再卖 #这个时候用yield就可以更贴近实际的实现上面的问题 # import time # def product_baozi(): # for i in range(1,101): # print('正在生产包子中。。。。') # yield '做好了第%s个包子'%i # time.sleep(3) # print('来了第%s个顾客买了一个包子'%i) # # res = product_baozi() # print(res) #输出结果为<generator object product_baozi at 0x000001E499D35518> # #此时我们开始执行product_baozi的函数 # print(res.__next__()) #输出结果:正在生产包子中。。。。\n做好了第1个包子 # print(res.__next__()) #输出结果:来了第1个顾客买了一个包子\n正在生产包子中。。。。\n做好了第2个包子 # print(res.__next__()) #输出结果:来了第2个顾客买了一个包子\n正在生产包子中。。。。\n做好了第3个包子 #结果yield的操作,这个生产包子卖包子显得更贴近实际了 #从一个文件中获取人口总数信息,并且分别求出占比 #文件内容: # {'name':'北京','population':4343443} # {'name':'山东','population':1000000} # {'name':'山西','population':313435} # {'name':'河北','population':3110330} # {'name':'台湾','population':3110300} # def get_population(): # with open('test_1.txt','r',encoding = 'utf-8') as f: # for i in f: #是文章每个单句生成一个生成器 # yield i #每次只获取一行 # res = get_population() #res就是一个迭代器 # # pop = eval(res.__next__()['population']) # a = sum(eval(i)['population'] for i in res) #特别注意的部分,一个迭代器只能运行一次,如果想继续使用必须重新获取迭代器 # print('总人口',a) # # res_1 = get_population() #重新获取迭代器 # for i in res_1: # p = eval(i) # zhanbi = p['population']/a * 100 # print(p['name'],'人口占比为%.2f %%'%zhanbi) # send:最后一个能够触发生成器开始运行的方法 # 截止目前能够触发生成器运行的方式有__next__()、next()、send('给yield传一个变量,从而达到触发生成器运行') # 示例:吃包子,边吃边做包子 # import time # def chihuo(name): # while True: # print('%s我点了包子,赶紧给我上菜包子'%name) # time.sleep(0.5) # baozi = yield # print('%s吃完了%s'%(name,baozi)) # # def zuobaozi(lis): # for name in lis: # c = chihuo(name) # c.__next__() # for i in range(1,11): # time.sleep(0.5) # c.send('包子%s'% i) #此处是用send将包子+序号传到了chihuo()中的yield,/ # # 给变量baozi赋值的同时,触发生成器继续运行 # lis = ['zhoujielun','zhaolei','alex'] # # zuobaozi(lis) #题目:一定范围内能被3和7整除,返回所有数字的和以及个数 # def qiuhe(strats,ends): # count = 0 # sum_l = 0 # for i in range(strats,(ends+1)): # if i % 3 == 0 and i % 7 == 0: # sum_l += i # count += 1 # print('%s到%s之间的总和是:'%( strats , ends ), sum_l) # print('%s到%s之间的个数是:'%( strats , ends ), count) # return sum_l,count # # #求1到1000之间的吧! # qiuhe(1,1000) # 该题目要求使用递归的方法来写 # def qiuhe(start,end,a = [],b = []): # if start == end : # s_a = sum(a) # s_b = sum(b) # print('%s到%s之间的总和是:' % (start, end), s_a) # print('%s到%s之间的个数是:' % (start, end), s_b) # return s_a,s_b # elif start % 3 == 0 and start % 7 == 0: # a.append(1) # b.append(start) # res = qiuhe(start+1,end, a , b) # return res # else: # res = qiuhe(start + 1, end, a, b) # return res # # qiuhe(10,1000)
今天练习内容比较多,就是这些啦,要抓紧复习,感觉最开始的东西开始慢慢的忘掉了,可怕!!!
今天才11天呐。
标签:__,Python,res,生成器,包子,yield,next,print,往期 来源: https://www.cnblogs.com/xiaoyaotx/p/12416782.html