迭代器与迭代对象

打印 上一主题 下一主题

主题 916|帖子 916|积分 2748

可迭代对象与迭代器

可迭代协议:可迭代对象必须包含__iter__方法,并且返回一个的迭代器
满足可迭代协议的对象称为可迭代对象。可迭代对象即可使用for …… in的对象。
迭代协议:满足迭代协议的对象时迭代器。

  • 包含__iter__方法,并且该方法返回迭代器本身
  • 包含__next__方法,调用该方法返回下一个值,当没有值可返回时,抛出StopIteration异常终止迭代。
  1. from collections.abc import Iterable, Iterator
  2. class Iter_obj:
  3.     def __init__(self, n) -> None:
  4.         self.n = n
  5.         self.data = [i for i in range(n)]
  6.     def __iter__(self):
  7.         """返回一个迭代器"""
  8.         return iter(self.data)  # list时可迭代对象但不是可迭代器,
  9.         # 基本数据类型的容器类型都是可迭代对象,但都不是迭代器
  10. class Iterator_:
  11.     def __init__(self, n):
  12.         self.n = n
  13.         self.start = 0
  14.     def __iter__(self):
  15.         """返回一个迭代器"""
  16.         return self  # 实现了__iter__和__next__方法的对象就是迭代器,所以返回本身
  17.    
  18.     def __next__(self):
  19.         if self.n>self.start:
  20.             self.start+=1
  21.             return self.start
  22.         else:
  23.             raise StopIteration()
  24. if __name__ == "__main__":
  25.     iter_obj = Iter_obj(3)
  26.     print(isinstance(iter_obj, Iterable))
  27.     for x in iter_obj:  # 可迭代对象可以使用for in语句
  28.         print(x)
  29.     iterator_ = Iterator_(5)
  30.     print(isinstance(iterator_, Iterator))
  31.     for x in Iterator_(5):
  32.         print(x)
  33.    
复制代码
iter方法和next方法

iter方法调用对象的__iter__方法返回一个迭代器。
next方法调用对象的__next__方法返回下一条数据
list、tuple、set、dict都可以使用iter方法得到对应的迭代器,然后可以使用next方法获取下一条数据。
  1. from collections.abc import Iterator, Iterable
  2. def iterable_to_iterator(obj):
  3.     print('-'*20)
  4.     s = type(obj)
  5.     print("%s is Iterable: %s"%(s, isinstance(obj, Iterable)))
  6.     print("%s is Iterator: %s"%(s, isinstance(obj, Iterator)))
  7.    
  8.     try:
  9.         iterator = iter(obj)
  10.         print("%s is Iterator: %s"%(iterator, isinstance(iterator, Iterator)))
  11.         while True:
  12.             print(next(iterator))
  13.     except StopIteration as e:
  14.         pass
  15.     finally:
  16.         print('-'*20)
  17. if __name__ == "__main__":
  18.     string = "python"
  19.     mylist = ['a', 'b', 'c']
  20.     myset = set([1,2,3])
  21.     mydict =  dict(zip(myset, mylist))
  22.     for obj in [string, mylist, myset, mydict]:
  23.         iterable_to_iterator(obj)
复制代码
常见可迭代器与可迭代对象
  1. from collections.abc import Iterator, Iterable
  2. def iterable_or_iterator(obj):
  3.    
  4.     s = type(obj)
  5.     print("%s is Iterable: %s"%(s, isinstance(obj, Iterable)))
  6.     print("%s is Iterator: %s\n"%(s, isinstance(obj, Iterator)))
  7. if __name__ == "__main__":
  8.     zip_ = zip([1,2],[3,4])
  9.     dic = dict(zip_)
  10.     map_ = map(int, ['1','2'])
  11.     enumerate_ = enumerate(['a','b','c'])
  12.     for obj in [list(), tuple(), set(), dict(), str(), range(3), zip_,map_, enumerate_,
  13.                 dic.keys(), dic.values(), dic.items()]:
  14.         iterable_or_iterator(obj)
  15.    
  16. # <class 'list'> is Iterable: True
  17. # <class 'list'> is Iterator: False
  18. # <class 'tuple'> is Iterable: True
  19. # <class 'tuple'> is Iterator: False
  20. # <class 'set'> is Iterable: True
  21. # <class 'set'> is Iterator: False
  22. # <class 'dict'> is Iterable: True
  23. # <class 'dict'> is Iterator: False
  24. # <class 'str'> is Iterable: True
  25. # <class 'str'> is Iterator: False
  26. # <class 'range'> is Iterable: True
  27. # <class 'range'> is Iterator: False
  28. # <class 'zip'> is Iterable: True
  29. # <class 'zip'> is Iterator: True
  30. # <class 'map'> is Iterable: True
  31. # <class 'map'> is Iterator: True
  32. # <class 'enumerate'> is Iterable: True
  33. # <class 'enumerate'> is Iterator: True
  34. # <class 'dict_keys'> is Iterable: True
  35. # <class 'dict_keys'> is Iterator: False
  36. # <class 'dict_values'> is Iterable: True
  37. # <class 'dict_values'> is Iterator: False
  38. # <class 'dict_items'> is Iterable: True
  39. # <class 'dict_items'> is Iterator: False
复制代码
zip、map、enumerate的返回值是迭代器,dict的keys、values、items的返回值和range的返回值都是可迭代对象,基本数据类型的list、tuple、set、dict、string都是可迭代对象

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金歌

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表