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天呐。

posted @ 2020-03-04 22:47  崆峒山肖大侠  阅读(182)  评论(1编辑  收藏  举报