Python 迭代器和可迭代

一、可迭代

1. 可迭代的判定

# 验证是否是迭代器或可迭代
from collections.abc import Iterable,Iterator  
>>> isinstance(list(),Iterable)
True
>>> isinstance(list(),Iterator)
False
>>> 

2. Iterable 可迭代的定义

可用for loop实现访问,或者是类中包含iter(),则称为可迭代。

# 自定义 iterable
from collections.abc import Iterable
class count1:
    def __init__(self, start=0):
        self.num=start
    def __iter__(self):
        return self
obj = count1(1)
print(isinstance(obj, Iterable)) # True
  1. 常见的list,tuple,dict,set,str
  2. 使用iter()后生成迭代器,也可以用next()访问
  3. 可迭代包含迭代器:即Iterable包含Iterators

二、Iterators 迭代器

A. 定义

  • 迭代中可以记忆自己的状态
  • 有__next__方法
    • 自动跳到下一个值
    • 在下一个值时更新状态
    • 结束时信号会raise StopIteration异常
      • 可用try…except来处理
    itr = iter([1,2,3])
    print(next(itr))
    print(next(itr))
    print(next(itr))
    # print(next(itr)) # StopIteration
    

可迭代的,且有__iter__方法,即迭代器

B. 生成迭代器iterators.iter()

  1. 如果可迭代的话,则获得迭代器
  2. 如果不可迭代的话,则通过索引生成迭代器
  3. 若均不满足,就raise TypeError
    • 可用try…except来处理

C. 迭代协议

  1. __iter__()
  2. __next__() 调用next()可以不断指向下一个值
  3. 所有可迭代的都可以用**内置函数 iter()**获得迭代器,之后可以使用next()
    • 常见的list,tuple,dict,set,str,均是Iterator的子类
    • open读取后,可以用next调用

D. 为什么要用迭代器

  1. lazy:不用考虑下一个是什么,自动next
  2. 有时节省时间和内存,相对list等数据结构(见例题)
  3. 可以生成无穷长的迭代器,且占用内存很小

E. 怎样制造迭代器******

  1. 对象导向的生成器
    可以自建一个class ,包含__init__ \ iter\ next(见例子)
    # 自定义 iterator
    class count1:
        def __init__(self, start=0):
            self.num=start
        def __iter__(self): # 记录自己的状态
            return self
        def __next__(self): # 返回到下一个值
            self.num += 1
            return self.num
    
  2. 生成器函数
    自建一个def,包含yield语句,收集元素,并返回一个generator对象,即迭代器。
    其中,yield语句可以是一个或多个,通过for循环,按顺序收集迭代值(见例子)
    def count2(start=0):
       num = start
       while True:
       		yield num
       		num += 1
    
    注:
    1. 当called时,会返回迭代器但不会立即运行。
    2. 可以做一个无穷的迭代器函数,要比对象导向的更简洁
  3. 生成器的表达式
    自建一个类似list的表达式 (x for x in L).
    L = list(range(1,11))
    cubes = (x**3 for x in L)
    
    注:
    1. 类似于for loop加append
    2. 比生成函数更简洁

总结

  1. 迭代器和可迭代的不同点是,迭代中是有属性next+iter,而可迭代中有iter或getitem
  2. 不同生成器的简洁性:表达式 > 函数 > 表达式
  3. return 和yield的比较
    • return
      函数的终点、返回值或者None、摧毁了所有的局部变量
    • yield
      暂停函数的执行、获取值不摧毁局部变量、之后会从停下来的地方接着运行
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值