一、什么是迭代器:

  迭代是Python最强大的功能之一,是访问集合元素的一种方式。

  迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。

  迭代器是一个可以记住遍历的位置的对象。

  迭代器的特点:只能往前不会后退。

  迭代器有两个基本的方法:iter() 和 next()

    1、iter方法:返回迭代器对象本身

    2、next方法:返回迭代器的下一个元素

  可迭代的:只要对象本身有__iter__方法,那它就是可迭代的。

  字符串,列表或元组对象都可用于创建迭代器:

list = [1,2,3,4] #list列表
r = iter(list)用iter方法将list转成迭代器赋值给r
print(next(r)) #用next方法使用迭代器r,并输出结果
print(next(r)) #因为迭代器是一次性的,so,要想看下面的内容,\
# 还得用next方法使用迭代器r,并输出结果
----------------以下是输出结果--------------------
1
2

  二、迭代器的优点:

    1、迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典,集合,文件);

    2、迭代器与列表比较,迭代器是惰性计算的,更节省内存。

  三、迭代器的缺点:

    1、无法获取迭代器的长度,使用不如列表索引取值灵活;

    2、一次性的,只能往后取值,不能倒着取值。就像象棋里卒一样不能倒着走。

  下面来用代码展示一下吧:

  使用next需要注意的:

d = {"a":1,"b":2,"c":3} #定义了一个字典
r = iter(d) #用iter方法将字典转成了一个迭代器并赋值给r
while True: #定义了一个循环
print(next(r)) #用next调用迭代器r
-------------------以下是输出的结果-------------------
a #一直循环next的话,超出了元素的个数的时候就会报错
b
c
Traceback (most recent call last) #报错的内容

  下面介绍一个方法,使不会报错:

d = {"a":1,"b":2,"c":3}
r = iter(d)
while True: #加上try之后,它会自己判断,超出后会自动break
try:
print(next(r))
except StopIteration:
break
-------------以下是输出结果---------------
a
b
c

  我们用for循环来试试:

d = {"a":1,"b":2,"c":3}
for i in d : #for循环,遍历字典的中的每一个元素
print(i)
--------------以下是输出的结果--------------
a
b
c

   总结:不难看出for的作用是遍历迭代器——对一个迭代器(实现了 __next__)或者可迭代对象(实现了 __iter__)。

  查看可迭代对象与迭代器对象:

from collections import Iterable,Iterator #调用模块
#以下是定义的不同数据类型
s='hello' #字符串
l=[1,2,3] #列表
t=(1,2,3) #元组
d={'a':1,'b':2} #字典
set1={1,2,3,4} #集合
f=open('a.txt') #文件 #都是可迭代的(只有可迭代的才有iter方法)
s.__iter__()
l.__iter__()
t.__iter__()
d.__iter__()
set1.__iter__()
f.__iter__() #查看是否是可迭代对象(True为是,False为否)
print(isinstance(s,Iterable))--------->True #字符串
print(isinstance(l,Iterable))--------->True #列表
print(isinstance(t,Iterable))--------->True #元组
print(isinstance(d,Iterable))--------->True #字典
print(isinstance(set1,Iterable))--------->True #集合
print(isinstance(f,Iterable))--------->True #文件 #查看是否是迭代器(Turn为是,False为否)
print(isinstance(s,Iterator))--------->False #字符串
print(isinstance(l,Iterator))--------->False #列表
print(isinstance(t,Iterator))--------->False #元组
print(isinstance(d,Iterator))--------->False #字典
print(isinstance(set1,Iterator))--------->False #集合
print(isinstance(f,Iterator))--------->True #文件

  四、生成器

  定义:

    函数内带有yield关键字,那么这个函数执行的结果就是生成器(generator)。

    跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

    在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。

  下面用实例使用 yield 实现斐波那契数列:

def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成 while True:
try:
print (next(f), end=" ")
except StopIteration:
break
-----------以下是输出的结果-------------
0 1 1 2 3 5 8 13 21 34 55

  总结yield的功能:

    1.相当于把__iter__和__next__方法封装到函数内部

    2.与return比,return只能返回一次,而yield能返回多次

    3.函数暂停已经继续运行的状态是通过yield保存的

  生成器与return有何区别?

  return只能返回一次函数就彻底结束了,而yield能返回多次值。

  return作用:

  在一个生成器中,如果没有return,则默认执行到函数完毕;

  如果遇到return,在执行过程中 return,则直接抛出 StopIteration 终止迭代。

  yield的表达式形式:

  food = yield

#定义阶段
def eater(name):
print('%s start to eat' % name)
while True:
food = yield
print('%s eat %s' % (name, food))
#调用阶段
e = eater('egon')
next(e)
print(e.send("盖饭"))
------------------以下是输出结果---------------------
egon start to eat
egon eat 盖饭

  e.send与next(e)的区别:

    1、如果函数内yield是表达式形式,那么必须先next(e)

    2、二者的共同之处是都可以让函数在上次暂停的位置继续运行,不一样的地方在于send在触发下一次

代码的执行时,会顺便给yield传一个值。

  实操一:

  迭代器的应用:

    实现的功能:linux命令:cat a.txt | grep apple

    要求1:定义迭代器函数cat;

    要求2:定义迭代器函数grep;

    要求3:模拟管道的功能,将cat的输出结果作为grep的输入参数

def cat(file_path):
'''输出a.txt里的内容'''
with open(file_path,mode="r",encoding="utf8") as f:#打开文件a.txt
line = f.read()#读取文件内容
yield line #返回值line
def grep(cho,lines):
'''将a.txt里的内容作为参数传进来进行匹配'''
for ab in lines: #循环a.txt
if cho in ab: #判断输入的元素是否在a.txt里
yield cho #在就返回值给g2
else: #没在a.txt里面的情况
print("\33[31;1m不存在\33[0m")
g1 = cat("a.txt") #输入参数调用函数cat,并赋值给g1
g2=grep("apple",g1) #将g1作为参数调用函数grep,并赋值给g2
for i in g2: #相当于迭代器的next方法(next(g2))
print("\33[42;1m%s\33[0m"%i) #打印输出结果

  实操二

  生成器的应用:

  把下述函数改成生成器的形式,执行生成器函数到一个生成器g,然后,每次g.send(url),打印页面的内容,利用g可以无限send(url)。

def get(url):
def index():
return urlopen(url).read()
return index

  只用一层函数的方法:

def get():
print("开始爬虫了!")
while True:
url = yield #每次执行到这,都会在这等着用户的下次输入
print(urlopen(url).read())
print("\33[31;1m完成了一次爬虫\33[0m")
g = get() #调用get函数并赋值给g
next(g) #用next方法调用生成器get
print(g.send("http://www.baidu.com")) #send一个网址
print(g.send("http://www.sina.com"))#可以无限的send(url)
-----------------------以下是输出的结果----------------------------
开始爬虫了!
b'<!DOCTYPE html>\n<!--STATUS OK-->\n\r\n\r\n\r\n\r\n
<<<<< 中间内容省略>>>>>
d dmp -->\n\n<!-- body code end -->\n</body>\n</html>'
完成了一次爬虫

  用闭包函数的方法:

#定义函数阶段
def get():
def index():
print("开始爬虫了!")
while True:
url = yield #每次在这等着用户的输入
print(urlopen(url).read()) #打印爬虫的结果
print("\33[31;1m完成了一次爬虫\33[0m") #爬虫完毕打印
return index #返回 index的内存地址
#调用函数阶段
g = get() #调用函数get,并将返回值赋值给g
g2 = g() #将get的返回值g调用即index函数,并赋值给g2
next(g2) #用next方法调用g2,此时会停在yield那
print(g2.send("http://www.baidu.com")) #给url传参数
print(g2.send("http://www.sina.com")) #可以无限的send(url)
---------------------------以下是输出的结果--------------------------
  开始爬虫了!
  b'<!DOCTYPE html>\n<!--STATUS OK-->\n\r\n\r\n\r\n\r\n\r\n\r\
<<<<<中间的内容省略>>>>>
  </script>\r\n\r\n\n\n</body>\n</html>\n\r\n\r\n\r\n\n\r\n'
  完成了一次爬虫

  

python基础之迭代器与生成器的更多相关文章

  1. Python基础之迭代器和生成器

    阅读目录 楔子 python中的for循环 可迭代协议 迭代器协议 为什么要有for循环 初识生成器 生成器函数 列表推导式和生成器表达式 本章小结 生成器相关的面试题 返回顶部 楔子 假如我现在有一 ...

  2. python基础8 -----迭代器和生成器

    迭代器和生成器 一.迭代器 1.迭代器协议指的是对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2. ...

  3. 【Python基础】迭代器、生成器

    迭代器和生成器 迭代器 一 .迭代的概念 #迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单 ...

  4. 1.17 Python基础知识 - 迭代器和生成器初识

    可循环迭代的对象称为可迭代对象,迭代器和生成器函数是可迭代对象. 列表解析表达式:可以简单高效处理一个可迭代对象,并生成结果列表 示例代码: [ i ** 2 for i in range(10) ] ...

  5. Python高手之路【九】python基础之迭代器与生成器

    迭代器与生成器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外 ...

  6. python 基础(五) 迭代器与生成器

    迭代器和生成器 迭代器 iterator (1) 迭代对象: 可以直接作用于for循环的 称为可迭代对象(iterable)可以通过 isinstance 判断是否属于可迭代对象 可以直接作用于for ...

  7. python基础之迭代器、生成器、装饰器

    一.列表生成式 a = [0,1,2,3,4,5,6,7,8,9] b = [] for i in a: b.append(i+1) print(b) a = b print(a) --------- ...

  8. Python基础之迭代器、生成器

    一.迭代器: 1.迭代:每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值.例如:循环获取容器中的元素. 2.可迭代对象(iterable): 1)定义:具有__ite ...

  9. 7th,Python基础4——迭代器、生成器、装饰器、Json&pickle数据序列化、软件目录结构规范

    1.列表生成式,迭代器&生成器 要求把列表[0,1,2,3,4,5,6,7,8,9]里面的每个值都加1,如何实现? 匿名函数实现: a = map(lambda x:x+1, a) for i ...

随机推荐

  1. [js]使用百度编辑器uediter时遇到的一些问题(span,div等被过滤)

    在使用uediter编辑html代码的时候,div,span等标签会莫名其妙的被过滤掉,然后上网查资料,改了点配置: 1:在ueiter.all.js中找到allowDivTransToP me.se ...

  2. linqjs

    Project Descriptionlinq.js - LINQ for JavaScript Features implement all .NET 4.0 methods and many ex ...

  3. 省市联动-获取资源文件xml 获取nodes的方法要学会

    try { SAXReader reader = new SAXReader(); InputStream input = this.getClass().getResourceAsStream(&q ...

  4. 20165234 2017-2018-2《Java程序设计》课程总结

    2017-2018-2<Java程序设计>课程总结 一.作业链接汇总 每周作业链接 预备作业一:我期望的师生关系 预备作业二:学习基础和C语言基础调查 预备作业三:Linux安装及学习 第 ...

  5. Hadoop配置文件参数详解

    core-site.xml <configuration> <property> <name>hadoop.tmp.dir</name> <val ...

  6. P4843 清理雪道

    题目地址:P4843 清理雪道 上下界网络流 无源汇上下界可行流 给定 \(n\) 个点, \(m\) 条边的网络,求一个可行解,使得边 \((u,v)\) 的流量介于 \([B(u,v),C(u,v ...

  7. [BugBounty] Sleeping stored Google XSS Awakens a $5000 Bounty

    来源:https://blog.it-securityguard.com/bugbounty-sleeping-stored-google-xss-awakens-a-5000-bounty/ 理解 ...

  8. python骚操作之...

    python中的Ellipsis对象.写作:- 中文解释:省略 该对象bool测试是为真 用途: 1.用来省略代码,作用类似于pass的一种替代方案. from collections.abc imp ...

  9. 求逆序对 ----归并排 & 树状数组

    网上看了一些归并排求逆序对的文章,又看了一些树状数组的,觉得自己也写一篇试试看吧,然后本文大体也就讲个思路(没有例题),但是还是会有个程序框架的 好了下面是正文 归并排求逆序对 树状数组求逆序对 一. ...

  10. exiting pxe rom 无法启动

    背景 我这是给人装了多少次机器了,上千次不敢说,几百次是有了.有个奇怪现象,为什么每次总有新的问题呢,极少能一次成功的.除了让我涨了见识,没想到其他的用处.程序员修电脑,搞笑吧,还有找我修洗衣机的,说 ...