Python全栈开发之---迭代器、可迭代对象、生成器
1、什么叫迭代
现在,我们已经获得了一个新线索,有一个叫做“可迭代的”概念。
首先,我们从报错来分析,好像之所以1234不可以for循环,是因为它不可迭代。那么如果“可迭代”,就应该可以被for循环了。
这个我们知道呀,字符串、列表、元组、字典、集合都可以被for循环,说明他们都是可迭代的。
我们怎么来证明这一点呢?
from collections import Iterable l = [1,2,3,4]
t = (1,2,3,4)
d = {1:2,3:4}
s = {1,2,3,4} print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))
结合我们使用for循环取值的现象,再从字面上理解一下,其实迭代就是我们刚刚说的,可以将某个数据集内的数据“一个挨着一个的取出来”,就叫做迭代。
2、迭代器和协议
既什么叫“可迭代”之后,又一个历史新难题,什么叫“迭代器”?
虽然我们不知道什么叫迭代器,但是我们现在已经有一个迭代器了,这个迭代器是一个列表的迭代器。
我们来看看这个列表的迭代器比起列表来说实现了哪些新方法,这样就能揭开迭代器的神秘面纱了吧?
'''
dir([1,2].__iter__())是列表迭代器中实现的所有方法,dir([1,2])是列表中实现的所有方法,都是以列表的形式返回给我们的,为了看的更清楚,我们分别把他们转换成集合,
然后取差集。
'''
#print(dir([1,2].__iter__()))
#print(dir([1,2]))
print(set(dir([1,2].__iter__()))-set(dir([1,2]))) 结果:
{'__length_hint__', '__next__', '__setstate__'} iter_l = [1,2,3,4,5,6].__iter__()
#获取迭代器中元素的长度
print(iter_l.__length_hint__())
#根据索引值指定从哪里开始迭代
print('*',iter_l.__setstate__(4))
#一个一个的取值
print('**',iter_l.__next__())
print('***',iter_l.__next__())
这三个方法中,能让我们一个一个取值的神奇方法是谁?
没错!就是__next__
在for循环中,就是在内部调用了__next__方法才能取到一个一个的值。
那接下来我们就用迭代器的next方法来写一个不依赖for的遍历。
l = [1,2,3,4]
l_iter = l.__iter__()
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
这是一段会报错的代码,如果我们一直取next取到迭代器里已经没有元素了,就会抛出一个异常StopIteration,告诉我们,列表中已经没有有效的元素了。
这个时候,我们就要使用异常处理机制来把这个异常处理掉。
l = [1,2,3,4]
l_iter = l.__iter__()
while True:
try:
item = l_iter.__next__()
print(item)
except StopIteration:
break
3、可迭代对象
我们现在是从结果分析原因,能被for循环的就是“可迭代的”,但是如果正着想,for怎么知道谁是可迭代的呢?
假如我们自己写了一个数据类型,希望这个数据类型里的东西也可以使用for被一个一个的取出来,那我们就必须满足for的要求。这个要求就叫做“协议”。
可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法。
迭代器生成的对象就是可迭代对象
4、生成器
Python中提供的生成器:
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
生成器Generator:
本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)
特点:惰性运算,开发者自定义
import time
def genrator_fun1():
a = 1
print('现在定义了a变量')
yield a
b = 2
print('现在又定义了b变量')
yield b g1 = genrator_fun1()
print('g1 : ',g1) #打印g1可以发现g1就是一个生成器
print('-'*20) #我是华丽的分割线
print(next(g1))
time.sleep(1) #sleep一秒看清执行过程
print(next(g1))
def generator():
print(123)
content = yield 1
print('=======',content)
print(456)
yield2 g = generator()
ret = g.__next__()
print('***',ret)
ret = g.send('hello') #send的效果和next一样
print('***',ret) #send 获取下一个值的效果和next基本一致
#只是在获取下一个值的时候,给上一yield的位置传递一个数据
#使用send的注意事项
# 第一次使用生成器的时候 是用next获取下一个值
# 最后一个yield不能接受外部的值
#yield from def gen1():
for c in 'AB':
yield c
for i in range(3):
yield i print(list(gen1())) def gen2():
yield from 'AB'
yield from range(3) print(list(gen2())) yield from
Python全栈开发之---迭代器、可迭代对象、生成器的更多相关文章
- python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))
昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据. StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对 ...
- python全栈开发-Day11 迭代器、生成器、面向过程编程
一. 迭代器 一 .迭代的概念 迭代器即迭代的工具,那什么是迭代呢? 迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而 ...
- Python 全栈开发五 迭代器 生成器 装饰器
一.迭代器 迭代协议:对象必须提供一个next方法,执行该方法后会返回迭代的下一项或者抛出Stopiteration异常,终止迭代.切只能往前,不能倒退. 可迭代对象:遵循迭代写一点对象就是可迭代对象 ...
- python全栈开发_day13_迭代器和生成器
一:迭代器 1)可迭代对象 具有内置函数__iter__的数据就是可迭代对象 2)迭代器对象 具有内置函数__next__的数据就是迭代器对象 迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象 ...
- 巨蟒python全栈开发-第11天 第一类对象 闭包 迭代器
一.今日主要内容总览(重点) 1.第一类对象->函数名=>变量名 (1)函数对象可以像变量一样进行赋值 (2)还可以作为列表的元素进行使用 (3)还可以作为返回值返回 (4)还可以作为参数 ...
- python 全栈开发,Day14(列表推导式,生成器表达式,内置函数)
一.列表生成式 生成1-100的列表 li = [] for i in range(1,101): li.append(i) print(li) 执行输出: [1,2,3...] 生成python1期 ...
- python全栈开发- day14列表推导式、生成器表达式、模块基础
一.列表推导式 #1.示例 数据量小 egg_list=[] for i in range(10): egg_list.append('鸡蛋%s' %i) egg_list=['鸡蛋%s' %i fo ...
- python全栈开发学习_内容目录及链接
python全栈开发学习_day1_计算机五大组成部分及操作系统 python全栈开发学习_day2_语言种类及变量 python全栈开发_day3_数据类型,输入输出及运算符 python全栈开发_ ...
- python全栈开发从入门到放弃之迭代器生成器
1.python中的for循环 l = [1,2,3,4,5,6] for i in l: #根据索引取值 print(i) 输出结果: 1 2 3 4 5 6 2.iterable 可迭代的 可迭 ...
随机推荐
- 基于docker 如何部署surging分布式微服务引擎
1.前言 转眼间surging 开源已经有1年了,经过1年的打磨,surging已从最初在window 部署的分布式微服务框架,到现在的可以在docker部署利用rancher 进行服务编排的分布式微 ...
- Django-ORM增删改查
ORM对单表进行增删改查 一,增加记录 #第一种方式 b=Book(name="Linux",price=66,author="kelvin",pub_date ...
- 基于SpringBoot从零构建博客网站 - 整合lombok和mybatis-plus提高开发效率
在上一章节中<技术选型和整合开发环境>,确定了开发的技术,但是如果直接这样用的话,可能开发效率会不高,为了提高开发的效率,这里再整合lombok和mybatis-plus两个组件. 1.l ...
- Python爬取南京市往年天气预报,使用pyecharts进行分析
上一次分享了使用matplotlib对爬取的豆瓣书籍排行榜进行分析,但是发现python本身自带的这个绘图分析库还是有一些局限,绘图不够美观等,在网上搜索了一波,发现现在有很多的支持python的绘图 ...
- python接口自动化(十五)--参数关联接口(详解)
简介 我们用自动化新建任务之后,要想接着对这个新建任务操作,那就需要用参数关联了,新建任务之后会有一个任务的Jenkins-Crumb,获取到这个Jenkins-Crumb,就可以通过传这个任务Jen ...
- C#字符串的一些常用方法
字符串常用方法 string str =""; string[] strArray = str.Split('截取字符'); //按字符将字符串拆分为数组 str = str.Re ...
- php 通过header下载中文文件名 压缩包损坏或文件不存在的问题
开发中大家都是使用的utf8编码,昨天遇到一个奇坑,本是一件很小的问题,解决也浪费了个吧小时.废话不多说,植入正题: 文件下载方式:通过header二进制流文件下载需求: 文件上传保留文件名不变数据字 ...
- Dynamics 365中自定义工作流活动更新了输入输出参数后获取的方法
关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复245或者20170309可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...
- Odoo:全球第一免费开源ERP权威性能测试报告完整版(绝对珍藏)
Odoo平台简介 Odoo(以前叫OpenERP)是世界排名第一的开源ERP系统,最早由比利时一家公司开发,经过十几年发展,目前全世界Odoo的使用者超过2百万人,Odoo被翻译成几十种语言,Odoo ...
- 安卓开发笔记(二十二):读取本地(内置)html文件并实现和Javascript交互
实际上我们通常是使用WebView控件对本地html进行读取,这样就可以体会类似web app和安卓原生混合开发的乐趣了.在读取本地html并展示在前台的时候,并不需要在Androidmenifast ...