Python三大神器之迭代器详细版(小白都能看懂)

前言

介绍

    在python的学习中,我们通常会听到python三大神器着一说法,但是有的同学并不知道python三大神器是指哪三大神器,或许有的小伙伴听过而且学过python三大神器,但是由于时间的原因,其中的一些细节知识出现了遗漏,那么今天我们就给小伙伴们讲讲python的三大神器。

三大神器是哪三大

我们通常说的python三大神器是指迭代器,生成器和装饰器。

迭代器特点:

1.节省内存

迭代器在内存当中就相当于占了一个数据(元素)的内存。

2.惰性机制

不去调用next()或则__next__就不会出现下一个元素。

3.不能往回走,向前看

用过的数据回不去了,只能是nxet(),可以理解为单线程的,当然啦,如果你想重头开始,也不是不行,那么再去拿一个新的迭代器就可以了。

引入迭代器

    我们假设一下,不能使用for循环的情况下,怎么对字符串,集合,元组,列表,字典进行循环遍历呢(for循环的本质其实就是迭代器,后面会讲到)?对于列表,字符串呢,我们就拿它的索引,对索引进行遍历(用while哈),但是到了集合这里呢,这个方法就行不通了,这时候有好奇的小伙伴会问,为什么了?因为集合的无序性导致了它不存在索引这一说,那我们硬要遍历就只能够将索引变为其他的数据类型了。这样子,很多小伙伴们都会感到不便利,在实践中十分的不爽。显然,用同一种方法进行循环会便利得多,既然索引循环遍历这一方法搞不定,又有没有其他的方法呢?python为了解决这一问题,就引入了我们今天的主角了,那就是迭代器(基于可迭代协议)。

ps

这里要注意哈,并不是所有的数据类型都遵守可迭代协议,譬如int类型就不遵守

for i in 123456789:
print(i)

 这里的运行结果是

我们这里做个对比哈 

for i in "123":
print (i)

这行代码的运行结果是

很明显哈,int类型那里标注了一个not iterable,而字符串那里可以正常运行。

那么在这里,很多小伙伴们又会有另一个疑问了,那我怎么知道谁是可迭代的,谁是不可迭代的啊?别急,让我来讲讲一个妙招:在python里面有一个工具叫做dir,这个dir有什么用呢,它可以知道我们所输入的数据类型能执行哪些操作。

字符串类型的有

print(dir(int))

 int类型的有

print(dir(int))

__iter__就是可迭代的意思,字符串中有,但是int类型没有哈,所以int就不可以迭代(注意哈,bool类型也不可以迭代),下次,我们不清楚一种数据类型能否可以迭代,就可以使用这一种方法来看。

迭代器怎么用

正文

list=["python","ML","DL","Matlab"]
print(list.__iter__())

在这里头,我们创建了一个列表,列表里面有着四个字符串。我们采用了__iter__这一操作,让我们看看会发生些什么变化。

我们发现在这里,结果给出了一个地址。等等,有的同学会有疑问了,刚才不是说iter是迭代的意思吗,怎么现在又给出了一个地址了啊。小伙伴们,别慌哈,这里是用__iter__将我们传入的列表带到了一个迭代器的工具里头,那怎么才能够进行迭代呢,别急,这里我们只需加上__next__便可,顾名思义哈,next就是下一个,我们调用一次__next__,就会有一个项跑出来了,请小伙伴们看下面的代码:

list=["python","ML","DL","Matlab"]
a=list.__iter__()
print(dir(a))

在这里,我们能够发现所谓的迭代器是可以进行__next__这一个操作的,于是我们调用一下__next__着一可执行操作

list=["python","ML","DL","Matlab"]
a=list.__iter__()
b=a.__next__()
print(b)

执行结果为

注意哈,__next__一次只能出一项哈

如果想再出一项,那么就得再一次地调用__next__

list=["python","ML","DL","Matlab"]
a=list.__iter__()
b=a.__next__()
print(b)
b=a.__next__()
print(b)

其运行结果为:

想要多少,我们就调用几次__next__

此时,有的同学又会有个问题了,我调用五次呢,是不是又回到了一开始的哪一项呢

那话不多说,跑段代码试试吧:

list=["python","ML","DL","Matlab"]
a=list.__iter__()
b=a.__next__()
print(b)
b=a.__next__()
print(b)
b=a.__next__()
print(b)
b=a.__next__()
print(b)
b=a.__next__()
print(b)

 运行结果为

这里我们可以看到运行结果中出现了一个词,叫做StopIteration,顾名思义就是停止了迭代,那么这就和上面的假设相反了。

那么怎么才能重头开始呢,答案也很简单哈,那就是再拿一个新的迭代器

ps

有点同学会这样子写代码哈:

list=["python","ML","DL","Matlab"]
a=list.__iter__()
b=a.__next__()
n=0
while n<6:
 print (b) 
 n+=1

注意这是不行的

运行结果会变成下面这个样子

 

因为这样啊,就相当于你每次都拿的是b运行的结果

更有同学是这样做的:

list=["python","ML","DL","Matlab"]
a=list.__iter__()
b=a.__next__()
n=0
while n<6:
 print (b.__next__()) 
 n+=1

 注意哈,这样也是不行的

运行结果是会报错的

我们观察报错的原因就会发现,我们的b是字符串,并没有__next__这一可执行操作,感兴趣的小伙伴可以去执行一下dir这一查找操作。#可迭代对象没有__next__,迭代器可迭代(__iter__)

那么如果你想写一个循环,而不是一直地采用复制一下语句

b=a.__next__()
print(b)

那么你可以用下面的代码

list=["python","ML","DL","Matlab"]
n=0
a=list.__iter__()
while n<6:
 print (a.__next__()) 
 n+=1

这样看上去是不是简洁明了很多呢,那我们跑一下看看是不是和我们之前的结果是一样的

结果如下

for循环的内部工作机制

代码

我们一开始讲到假设不能用for循环会怎么样,那为什么加上这个前提条件后,会差别这么大呢?下面我们就来讲讲for循环的内部工作机制:

首先,我们讲讲for循环怎么用

list=["python","ML","DL","Matlab"]
for item in list:
    print(item)

这就是普通的for循环了,我们跑一下

那这些求知欲爆棚的小伙伴们肯定不满足于此啊,那我们来拆开for循环,来看看它是怎么工作的

list=["python","ML","DL","Matlab"]
a=iter(list)
while True:
    try:
        print(next(a))
    except StopIteration:
        break

解释

来,我们跑一下这段代码

这就是for循环的内部机制了,看看运行结果是不是和刚才的是一样的?

try是指尝试一下,如果代码能够正常运行的话,那么就运行冒号后面的代码

那么try了一下不能正常运行,这可能是由很多原因导致的,如果导致错误的原因是StopIteration,即停止迭代,那么我们就执行except StopIteration后面的代码。

总结

步骤

step1:调用__iter__来拿到迭代器

step2:利用迭代器,调用__next__来拿到每一项元素

step3:重复step2,直到出现StopIteration

要注意的点

1.如果想再拿到第一个元素,那么请再拿一个迭代器

2.不能等价代换,譬如

list=["python","ML","DL","Matlab"]
print (list.__iter__().__next__()) 
print (list.__iter__().__next__())
print (list.__iter__().__next__())
print (list.__iter__().__next__())
print (list.__iter__().__next__())

运行结果如下

这里就是哐哐地在拿新的迭代器

简单版

list=["python","ML","DL","Matlab"]
a=iter(list)
print(next(a))

运行结果

注意看:这里我们使用了iter()和next()这两个函数,就不用像刚刚那样写__iter__和__next__了

来,我们再改改上面的循环代码,让它更简洁

list=["python","ML","DL","Matlab"]
n=0
a=iter(list)
while n<6:
 print (next(a)) 
 n+=1

运行结果是一样的哈。 

谢谢各位小伙伴的阅读,不要忘了收藏点赞喔,顺便关注一下博主哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值