python笔记 | 迭代器

迭代器Iterator

🖊能被next()函数调用,并不断返回下一个值的对象称为迭代器(Iterator 迭代器对象),迭代器是访问集合元素的一种方式,是python中最具特色的功能之一。

🖊迭代器可以记住访问遍历的位置,从集合的第一个元素开始访问,直到集合中的所有元素被访问完毕。迭代器只能从前往后一个一个的遍历,不能后退。
🖊迭代器的优势在于支持自身遍历,同时,它的特点是单向非循环的,一旦完成遍历,再次调用就会报错。

比如:普通可迭代对象就像是子弹匣,它遍历就是取出子弹,在完成操作后又装回去,所以可以反复遍历(即多次调用for循环,返回相同结果);而迭代器就像是装载了子弹匣而不可拆卸的枪,进行它遍历或自遍历都是发射子弹,这是消耗性的遍历,是无法复用的(即遍历会有尽头)。

1.相关函数

iter()

功能: 把可迭代的对象转为一个迭代器对象          
参数: 可迭代的对象 (str,list,tuple,dict)
返回值:迭代器对象                    

next()

功能:调用迭代器,并返回迭代器中的下一个数据
2.迭代器取值

特点: 取出一个少一个,直到都取完,最后再取就会报错

迭代器取值方案:

             
1. next() 调用一次获取一次,直到数据被取完                   
2. list() 使用list函数直接取出迭代器中的所有数据              
3. for    使用for循环遍历迭代器的数据  

举例:

# 定义一个列表,是一个可迭代的对象
f4 = ['赵四','刘能','小沈阳','海参炒面']  
res = iter(f4)        # 把可迭代对象转为迭代器使用 iter()
print(res,type(res))  #<list_iterator object at 0x109063810> <class 'list_iterator'>

# 1.使用next()函数去调用迭代器对象
print(next(res))  #赵四
print(next(res))  #刘能

#2.使用list取值
r = list(res)
print(r)        #直接运行2,返回['赵四', '刘能', '小沈阳', '海参炒面']
                #运行完1再运行2,返回['小沈阳', '海参炒面']

#3.使用for循环
for i in res:
    print(i)    #直接运行3,返回:
'''
赵四
刘能
小沈阳
海参炒面
'''

# print(next(res))   #报错:StopIteration, 即超出可迭代的范围

3.检测迭代器和可迭代对象的方法

迭代器一定是一个可迭代的对象,可迭代对象不一定是迭代器

迭代是一种遍历元素的方式,按照实现方式划分,有外部迭代与内部迭代两种,支持外部迭代(它遍历)的对象就是可迭代对象,而同时还支持内部迭代(自遍历)的对象就是迭代器;按照消费方式划分,可分为复用型迭代与一次性迭代,普通可迭代对象是复用型的,而迭代器是一次性的。

from collections.abc import Iterator,Iterable
varstr = '123456'      #可迭代对象                                         
res = iter(varstr)     #可迭代对象+迭代器                                        
                                                         
r1 = isinstance(varstr,Iterable) # True 可迭代对象                   
r2 = isinstance(varstr,Iterator) # False 不是一个迭代器                
r3 = isinstance(res,Iterable)    # True 可迭代对象                      
r4 = isinstance(res,Iterator)    # True 是一个迭代器                     
print(r1,r2)                                                    
print(r3,r4)                                                    
type() 函数返回当前数据的类型,                                           
isinstance() 检测一个数据是不是一个指定的类型
4.迭代器切片

itertools模块的 islice()方法将迭代器与切片完美结合
为了更直观地感受迭代器内部的执行过程,我们自定义一个迭代器,以斐波那契数列为例:

from itertools import islice

class Fib:
    def __init__(self):
        self.prev = 0
        self.curr = 1

    def __iter__(self):
        return self

    def __next__(self):
        value = self.curr
        self.curr += self.prev
        self.prev = value
        return value

f = Fib()
print(list(islice(f, 0, 10)))
#返回[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Fib既是一个可迭代对象(因为它实现了 __iter__方法),又是一个迭代器(因为实现了 __next__方法)。
实例变量prev和curr用户维护迭代器内部的状态。
每次调用 next()方法的时候做两件事:

  • 1.为下一次调用 next()方法修改状态
  • 2.为当前这次调用生成返回结果

迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

itertools 模块的切片方法的实现逻辑参看下方官网提供的源码:

def islice(iterable, *args):
    # islice('ABCDEFG', 2) --> A B
    # islice('ABCDEFG', 2, 4) --> C D
    # islice('ABCDEFG', 2, None) --> C D E F G
    # islice('ABCDEFG', 0, None, 2) --> A C E G
    s = slice(*args)
    # 索引区间是[0,sys.maxsize],默认步长是1
    start, stop, step = s.start or 0, s.stop or sys.maxsize, s.step or 1
    it = iter(range(start, stop, step))
    try:
        nexti = next(it)
    except StopIteration:
        # Consume *iterable* up to the *start* position.
        for i, element in zip(range(start), iterable):
            pass
        return
    try:
        for i, element in enumerate(iterable):
            if i == nexti:
                yield element
                nexti = next(it)
    except StopIteration:
        # Consume to *stop*.
        for i, element in zip(range(i + 1, stop), iterable):
            pass

islice() 方法的索引方向是受限的,但它也提供了一种可能性:即允许你对一个无穷的(在系统支持范围内)迭代器进行切片的能力。这是迭代器切片最具想象力的用途场景。

5.小结

迭代器是一种特殊的可迭代对象,可用于它遍历与自遍历,但遍历过程是损耗型的,不具备循环复用性,因此,迭代器本身不支持切片操作;通过借助 itertools 模块,我们能实现迭代器切片,将两者的优势相结合,其主要用途在于截取大型迭代器(如无限数列、超大文件等等)的片段,实现精准的处理,从而大大地提升性能与效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值