Python 迭代器

可迭代对象:
什么是可以直接用于for循环的呢?
可以直接用于for的数据类型一般分为两种:
1.集合数据类型:
list、tuple、dict、set、string…
2.generator,包括生成器和带yield的generator function

如何判断一个对象是否是可迭代对象?
答:isinstance()

isinstance()函数判断一个对象是否是一个已知的类型
语法:isinstance(object,classinfo)
(1)object—>实例对象
(2)classinfo—>可以是直接或间接类名、基本类型或者由它们组成的
元组返回值。如果对象类型与classinfo的类型相同则返回True,否则返回False。
在这里插入图片描述

在这里面,首先我导入的Iterable的包,也就是可迭代对象,下面的四条语句是分别查看
列表、元组、字典、字符串的类型,可以看到他们四个都是可迭代对象,当然,可迭代
对象远不止这些,这里只是给大家一个概念,并且看一下isinstance的使用方法。
如果你还不能理解的话,可以想一下,你有没有写过这样一句话(for i in [1,2,3,4,5]),
这是一个循环的表示方法,这里面就是在循环列表中的元素,来实现内部语句块。
也可以说成是遍历这个列表,当然也就是迭代了。

在这里插入图片描述什么是迭代器?
迭代器即用来迭代取值的工具,而迭代是重复反馈过程的活动,其目的通常是为了逼近所需的目标或结果,每一次对过程的重复称为一次迭代,而每一次迭代得到的结果会作为下一次迭代的初始值,单纯的重复并不是迭代。

while True:
    content = input().strip()
    print(content)

下述while循环才是一个迭代过程,不仅满足重复,而且以每次重新赋值后的index值作为下一次循环中新的索引进行取值,反复迭代,最终可以取尽列表中的值.

li=["Megan","Penny","Eason","Alice","Marry"]

index=0
while index< len(li):
    print(li[index])
    index+=1

迭代器对象
调用obj.iter()函数返回的结果就是一个迭代器对象(Iterator)。迭代器对象是内置有iter()和next()方法的对象,打开的文件本身就是一个迭代器对象,执行迭代器对象.iter()方法得到的仍然是迭代器本身,而执行迭代器.next()方法就会计算出迭代器中的下一个值。迭代器是python提供的一种统一的,不依赖索引的迭代取值方式,只要存在多个值,无论序列类型还是非序列类型都可以按照迭代器的方式取值。

listA = [1,2,3,4,5,6]
for i in listA:#listA是可迭代对象
    print(i)

d = iter(listA)
print(d,type(d))#<list_iterator object at 0x0000025E4C009278> <class 'list_iterator'>
#转化为迭代器

# print(next(d))
# print(next(d))

try:
    while True:
        print(next(d))
except StopIteration as e:
    print(e)

# for i in d:
#     print(i)

"""
迭代器三种取值的方式:
1.next()  每调用一次next(),就取一次值,迭代器里就少一个值,值取完毕后,会出错
2.转化为list()列表
3.for循环遍历取值
"""

s1 = "abcd"
print(s1,type(s1))#abcdertyuio <class 'str'>

for i in s1:
    print("i:",i)
#s1是字符串,是可迭代的对象,现在把它转化为迭代器
s2 = iter(s1)
print(s2,type(s2))#<str_iterator object at 0x00000137B2979208> <class 'str_iterator'>

#1.通过next()取值
# print("first:",next(s2))
# print("second:",next(s2))
# print("third:",next(s2))
# print("forth:",next(s2))
#现在迭代器里的值已经被取出完了,如果再用next()函数调用会出错 StopIteration
# print("fifth:",next(s2)) #会出错 StopIteration

#2.list()函数
# s3_li = list(s2)
# print(s3_li,type(s3_li))#由于上面通过next()已经取完值,所以是空列表,[] <class 'list'>,如果把上面注销,会有值
# for i in s3_li:
#     print("i:",i)

#3.for循环直接遍历迭代器,即可取值
for i in s2:
    print("for循环直接取值:",i)



#迭代器取值特点:取出一个少一个,直到取完。

for循环原理
有了迭代器后,我们便可以不依赖索引取值了,使用while循环的实现方式如下:

li=["Megan","Penny","Eason","Alice","Marry"]
name=iter(li)#通过iter()函数转化为迭代器
print(name,type(name))#<list_iterator object at 0x000002A62C129BE0> <class 'list_iterator'>
while True:
    try:
        print(next(name))
    except StopIteration:#捕捉异常终止循环
        break
"""
输出结果:
Megan
Penny
Eason
Alice
Marry
"""

for 循环又称为迭代循环,in后可以跟任意可迭代对象,上述while循环可以简写为:

li=["Megan","Penny","Eason","Alice","Marry"]
for name in li:
    print(name)
"""
输出结果:
Megan
Penny
Eason
Alice
Marry
"""

for循环在工作时,首先会调用可迭代对象li内置的iteration方法拿到一个可迭代对象,然后再调用该迭代对象的next()方法将取到的值赋给item执行循环体完成一次循环,周而复始,知道捕捉StopIteration异常,结束迭代.

迭代器的优点与缺点
基于索引的迭代取值,所有迭代的状态都保存在了索引中,而基于迭代器实现迭代的方式不再需要索引,所有迭代的状态都保存在迭代器中,然而这种处理方式优点与缺点并存。
优点:
1.为序列和非序列提供了一种统一的迭代取值方式。
2.惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值,就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。
缺点:
1.除非取尽,否则无法获取迭代器的长度。
2.只能取下一个值,不能回到开始,更像是‘一次性的’,迭代安全产生后的唯一目标就是重复执行方法直到值取尽,否则就会停留在某个位置,等待下一次调用next;若是要再次迭代同个对象,你只能重新调用iter()方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。

生成器也是可迭代对象。

《迭代器不一定是生成器,生成器一定是迭代器
凡是可作用于 for 循环的对象都是 Iterable 类型; 凡是可作用于 next() 函数的对象都是 Iterator 类型。》

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

可以使用isinstance()判断一个对象是否是Iterator对象:
在这里插入图片描述

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

把list、dict、str等Iterable变成Iterator可以使用iter()函数:
在这里插入图片描述
为什么list、dict、str等数据类型不是Iterator?

这是因为python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不
断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是
一个有序数列,但我们却不能提前知道序列的长度,只有不断通过next()函数实现按需要计算下一个数据,所以Iterator的计算是惰性的 ,只有在需要时返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

小结:
1.凡是可作用于for循环的对象都是Iterable类型;
2.凡是可作用于next()函数对象都是Iterator类型,它们表示一个惰性计算的序列。

3.即:
迭代器与可迭代
可迭代(可以for遍历)
迭代器(有next方法)

4.集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

5.Python的for循环本质上就是通过不断调用next()函数实现的,例如:

for x in [1,2,3,4,5]:
	pass

等价于:

#首先获得Iterator对象
info = iter([1,2,3,4,5]]
while True:
	x = next(info)#获得下一个值

6.关系举例:

from collections.abc import Iterator,Iterable

temp = (x*x for x in range(5))

print(temp,type(temp))

print(isinstance(temp,Iterator))
print(isinstance(temp,Iterable))
print(next(temp))

for i in temp:
    print(i)

info = [1,2,3,4,5,6]
print(isinstance(info,Iterable))
print(isinstance(info,Iterator))

info = iter(info)
print(isinstance(info,Iterator))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值