Day 20 迭代器、生成器
一、 迭代器
1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)
2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个iter()方法)
3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象
二、python中for循环机制
for循环的本质:循环所有对象,全都是使用迭代器协议。
正本清源:
很多人会想,for循环的本质就是遵循迭代器协议去访问对象,那么for循环的对象肯定都是迭代器了啊,没错,那既然这样,for循环可以遍历(字符串,列表,元组,字典,集合,文件对象),那这些类型的数据肯定都是可迭代对象啊?但是,我他妈的为什么定义一个列表l=[1,2,3,4]没有l.next()方法。
(字符串,列表,元组,字典,集合,文件对象)这些都不是可迭代对象,只不过在for循环式,调用了他们内部的iter方法,把他们变成了可迭代对象
然后for循环调用可迭代对象的next方法去取值,而且for循环会捕捉StopIteration异常,以终止迭代
循环访问方式
#for循环l本质就是遵循迭代器协议的访问方式,先调用diedai_l=l.__iter__()方法,或者直接diedai_l=iter(l),然后依次执行diedai_l.next(),直到for循环捕捉到StopIteration终止循环
#for循环所有对象的本质都是一样的原理
for循环
序列类型字符串,列表,元组都有下标,你用上述的方式访问,perfect!但是你可曾想过非序列类型像字典,集合,文件对象的感受,for循环就是基于迭代器协议提供了一个统一的可以遍历所有对象的方法,即在遍历之前,先调用对象的iter方法将其转换成一个迭代器,然后使用迭代器协议去实现循环访问,这样所有的对象就都可以通过for循环来遍历了,而且你看到的效果也确实如此,这就是无所不能的for循环
生成器
什么是生成器?
可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的iter方法),所以生成器就是可迭代对象
生成器分类及在python中的表现形式:
(Python有两种不同的方式提供生成器)
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
为何使用生成器之生成器的优点
(Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。
生成器小结:
1.是可迭代对象
2.实现了延迟计算,省内存啊
3.生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处,其余的可迭代对象可没有这点好处。
生成器函数
生成器表达式和列表解析
1.把列表解析的[]换成()得到的就是生成器表达式
2.列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
3.Python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。例如, sum函数是Python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以,我们可以直接这样计算一系列值的和
生成器总结:
语法上和函数类似:生成器函数和常规函数几乎是一样的。它们都是使用def语句进行定义,差别在于,生成器使用yield语句返回一个值,而常规函数使用return语句返回一个值
自动实现迭代器协议:对于生成器,Python会自动实现迭代器协议,以便应用到迭代背景中(如for循环,sum函数)。由于生成器自动实现了迭代器协议,所以,我们可以调用它的next方法,并且,在没有值可以返回的时候,生成器自动产生StopIteration异常
状态挂起:生成器使用yield语句返回一个值。yield语句挂起该生成器函数的状态,保留足够的信息,以便之后从它离开的地方继续执行。
优点一:生成器的好处是延迟计算,一次返回一个结果。也就是说,它不会一次生成所有的结果,这对于大数据量处理,将会非常有用。
优点二:生成器还能有效提高代码可读性。
这里,至少有两个充分的理由说明 ,使用生成器比不使用生成器代码更加清晰:
使用生成器以后,代码行数更少。大家要记住,如果想把代码写的Pythonic,在保证代码可读性的前提下,代码行数越少越好
不使用生成器的时候,对于每次结果,我们首先看到的是result.append(index),其次,才是index。也就是说,我们每次看到的是一个列表的append操作,只是append的是我们想要的结果。使用生成器的时候,直接yield index,少了列表append操作的干扰,我们一眼就能够看出,代码是要返回index。
这个例子充分说明了,合理使用生成器,能够有效提高代码可读性。只要大家完全接受了生成器的概念,理解了yield语句和return语句一样,也是返回一个值。那么,就能够理解为什么使用生成器比不使用生成器要好,能够理解使用生成器真的可以让代码变得清晰易懂。
注意事项:生成器只能遍历一次
知识点程序:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "DaChao"
# Date: 2017/6/15 ######################################################
#迭代器
###################################################### # dic = {"a":1,"b":2,"c":3} # aa = dic.__iter__()
# print(aa.__next__())
# print(aa.__next__())
# print(aa.__next__())
# print(aa.__next__()) # lit = ['a','b','c']
#
# bb = lit.__iter__()
# print(bb.__next__())
# print(bb.__next__())
# print(bb.__next__())
# print(bb.__next__()) ######################################################
#修饰器引进参数 Y
###################################################### # def deco(auth_type = "file"):
# def auth(func):
# def wrapper(*args,**kwargs):
# if auth_type == "file":
# print("文件的认证方式!")
# elif auth_type == "Idap":
# print("Idap的认证方式!")
# elif auth_type == "mysql":
# print("mysql的认证方式!")
# else:
# print("不知道的认证方式!")
# return wrapper
# return auth
# #
# @deco() #引进参数,如例,默认为auth_type="file"
# def index():
# print("Welcome to index!")
#
# index() ######################################################
#制作缓存
###################################################### # import os
# from urllib.request import urlopen
#
# cache_path = r"D:\Python\study\Day 8\cache.txt"
# def cache(func):
# def wrapper(*args,**kwargs):
# if os.path.getsize(cache_path): #有缓存
# with open(cache_path,"rb") as f:
# res = f.read()
# else:
# res = func(*args,**kwargs) #下载
# with open(cache_path,"wb") as f: #制作缓存
# f.write(res)
# return res
# return wrapper
#
# @cache
# def get(url):
# '''
# 读取网站并返回其内容
# :param url:
# :return:
# '''
# return urlopen(url).read() #注意指令,读出内容并返回
#
# print(get("https://www.yinxiang.com/webclipper/guide/")) ######################################################
#从数据库读取用户名和密码 Y
###################################################### # aaa_path = r"D:\Python\study\Day 8\aaa.txt" # r后面内容不转义
#
# def check(func):
# def wrapper(*args,**kwargs):
# usrname = input("Please input your name: ").strip()
# echo = input("Please input your echo: ").strip()
# with open(aaa_path,"r",encoding="utf-8") as f:
# usr_dic = eval(f.read())
# if usrname in usr_dic and echo == usr_dic[usrname]:
# print("Loggin successful!")
# func(*args,**kwargs)
# else:
# print("Loggin error!")
# return wrapper
#
# @check
# # def index():
# # print("Welcome to my world!")
#
# # index()
# def index(name):
# print("Welcome to %s`s world!" %name)
#
# index("dachao") ######################################################
#文件模拟数据存取 Y
###################################################### # usr_dic = {
# "egon":"123",
# "alex":"alex3714",
# "wupeiqi":"321",
# "yuanhao":"123123"
# }
#
# with open("aaa.txt","w",encoding="utf-8") as f:
# f.write(str(usr_dic)) #write 只能写入字符串
#
# with open("aaa.txt","r",encoding="utf-8") as f:
# res = f.read()
# # print(res,type(res))
# usr_dic=eval(res)
# print(usr_dic,type(usr_dic)) ######################################################
#eval功能:提取字符串命令并执行结果 Y
######################################################
# eval("print('hello world')") ######################################################
#注释修改功能 Y
######################################################
# from functools import wraps #调用内部函数 wraps
#
# def check_xiushi(func):
# '''
# 修饰器:check_xiushi
# :param func:
# :return:
# '''
# @wraps(func) #必须在闭包上面,实现保留原始func功能的作用
# def wrapper():
# '''
# 修饰器:闭包函数。
# :return:
# '''
# print("我是修饰器!")
# func()
# # wrapper.__doc__ = func.__doc__ #在调用阶段,实现
# return wrapper
#
# @check_xiushi
# def check():
# '''
# check function
# :return:
# '''
# print("Hello world!") # check()
# print(check.__doc__)
# print(help(check)) # print(check.__name__)
# check.__wrapped__() #调用wraps后,执行原始check函数
knowledge
作业:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "DaChao"
# Date: 2017/6/15 # 四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
# 注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式 # cache_path = r"D:\Python\study\Day 8\cache.txt"
#
# login_dic = {
# "usr":None,
# "status":False
# }
#
#
# def check(func):
# '''
# 用户登录验证,一次成功,后期不需要再次验证!
# :param func:
# :return:
# '''
# def wrapper():
# if login_dic["usr"] and login_dic["status"]:
# res = func()
# return res
# usrname = input("Please input your name: ")
# echo = input("Please input your echo: ")
# with open(cache_path,"r",encoding="utf-8") as f:
# usr_dic = eval(f.read())
# if usrname in usr_dic and echo == usr_dic[usrname]:
# login_dic["usr"] = usrname
# login_dic["status"] = True
# print("Loggin successful!")
# func()
# else:
# print("Loggin err!")
# return wrapper
#
# @check
# def index():
# print("Welcome to my world!")
# @check
# def index1():
# print("hahahaha") # 五:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
# 六:为题目五编写装饰器,实现缓存网页内容的功能:
# 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,
# 否则,就去下载,然后存到文件中 # import os
# from urllib.request import urlopen
#
# cache_path = r"D:\Python\study\Day 8\cache.txt"
# def cache(func):
# def wrapper(*args,**kwargs):
# if os.path.getsize(cache_path): #有缓存
# with open(cache_path,"rb") as f:
# res = f.read()
# else:
# res = func(*args,**kwargs) #下载
# with open(cache_path,"wb") as f: #制作缓存
# f.write(res)
# return res
# return wrapper
#
# @cache
# def get(url):
# '''
# 读取网站并返回其内容
# :param url:
# :return:
# '''
# return urlopen(url).read() #注意指令,读出内容并返回
#
# print(get("https://www.yinxiang.com/webclipper/guide/")) # 七:还记得我们用函数对象的概念,制作一个函数字典的操作吗,
# 来来来,我们有更高大上的做法,在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
work
Day 20 迭代器、生成器的更多相关文章
- Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化
本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...
- Python 迭代器&生成器
1.内置参数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice ...
- Python学习笔记——基础篇【第四周】——迭代器&生成器、装饰器、递归、算法、正则表达式
目录 1.迭代器&生成器 2.装饰器 a.基本装饰器 b.多参数装饰器 3.递归 4.算法基础:二分查找.二维数组转换 5.正则表达式 6.常用模块学习 #作业:计算器开发 a.实现加减成熟及 ...
- python各种模块,迭代器,生成器
从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能) 本质就是.py结尾的python文件(文件名:test.py,对应的模块名就是test) 包:用来从逻辑上组织模块的,本质就是一个目 ...
- Python基础-迭代器&生成器&装饰器
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 我现在有个需求,看 ...
- 迭代器/生成器/装饰器 /Json & pickle 数据序列化
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...
- Learn day5 迭代器\生成器\高阶函数\推导式\内置函数\模块(math.time)
1.迭代器 # ### 迭代器 """能被next调用,并不断返回下一个值的对象""" """ 特征:迭代器会 ...
- Python装饰器、迭代器&生成器、re正则表达式、字符串格式化
Python装饰器.迭代器&生成器.re正则表达式.字符串格式化 本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用 ...
- python杂记-4(迭代器&生成器)
#!/usr/bin/env python# -*- coding: utf-8 -*-#1.迭代器&生成器#生成器#正确的方法是使用for循环,因为generator也是可迭代对象:g = ...
- python 迭代器 生成器
迭代器 生成器 一 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...
随机推荐
- python--字符编码理解
一.字符编码简史: 美国:1963年 ASCII (包含127个字符 占1个字节) 中国:1980年 GB2312 (收录7445个汉字,包括6763个汉字和682个其它符号) 1993年 GB13 ...
- 【线程池】ExecutorService与quartz搭配出现的问题
问题描述: 使用quartz定时推送微信公众号模板消息,一分钟推送一次,定时器里面使用了一个ExecutorService线程池,大小为5个. 批量获取数据之后,全部数据都被分配到n/5的线程池里面等 ...
- vue $emit子组件传出多个参数,如何在父组件中在接收所有参数的同时添加自定义参数
Vue.js 父子组件通信的十种方式 前言 很多时候用$emit携带参数传出事件,并且又需要在父组件中使用自定义参数时,这时我们就无法接受到子组件传出的参数了.找到了两种方法可以同时添加自定义参数的方 ...
- 【netbeans】netbeans utf-8编码
首先,在你的netbeans的安装文件夹里面找到etc这个文件夹,打开,在里面找到netbeans.conf这个文件,打开,找到这一句netbeans_default_options="-J ...
- python-numpy-pandas
目录 numpy 模块 创建矩阵方法: 获取矩阵的行列数 切割矩阵 矩阵元素替换 矩阵的合并 通过函数创建矩阵 矩阵的运算 pandas模块 series (一维列表) DataFrame DataF ...
- 这五本Python急速入门必读的书,送给正在学习Python的你!
书籍是人类进步的阶梯,这句话从古至今都是适用的.为什么会这么说呢?书籍,它记录了人们实践的经验,这些经验有助于我们快速的学习,对于编程学习来说也不例外,今天就给大家带来了以下的书籍干货,希望能够帮助到 ...
- Docker工具
虚拟化 什么是虚拟化 在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源, 如服务器.网络.内存及存储等,予以抽象.转换后呈现出来, 打破实体结构间的 ...
- ACM-ICPC 2016 Qingdao Preliminary Contest G. Sort
Recently, Bob has just learnt a naive sorting algorithm: merge sort. Now, Bob receives a task from A ...
- 2019 study list
分析工具: (1)SQL select from where group by having order by limit 运算符(算数运算符+-*/.比较运算符>< ...
- 【Jenskins】安装与配置
Jenskins教程:http://www.yiibai.com/jenkins/ 一.Jenskins的安装 1.jenskins下载和启动 Jenskins下载地址:https://jenkins ...