谈谈Python 中的迭代器模式

谈谈Python 中的迭代器模式,第1张

软件开发领域中,人们经常会用到这一个概念——“设计模式”(design pattern),它是一种针对软件设计的共性问题而提出的解决方案。在一本圣经级的书籍《设计模式:可复用面向对象软件的基础》(1991年,Design Patterns - Elements of Reusable Object-Oriented Software)中,它提出了23种设计模式。迭代器模式就是其中的一种,在各种编程语言中都得到了广泛的应用。

本文将谈谈 Python 中的迭代器模式,主要内容:什么是迭代器模式、Python 如何实现迭代器模式、itertools 模块创建迭代器的方法、其它运用迭代器的场景等等,期待与你共同学习进步。

1、什么是迭代器模式?

维基百科有如下定义:

迭代器是一种最简单也最常见的设计模式。它可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。——维基百科

简单地说,迭代器模式就是一种通用性的可以遍历容器类型(如序列类型、集合类型等)的实现方式。使用迭代器模式,可以不关心遍历的对象具体是什么(如字符串、列表、字典等等),也不需要关心遍历的实现算法是什么,它关心的是从容器中遍历/取出元素的结果。

按遍历方式划分,迭代器可分为内部迭代器与外部迭代器,它们的区别在于执行迭代动作与维持迭代状态的不同。

通常而言,迭代器是一次性的,当迭代过一轮后,再次迭代将获取不到元素。

2、Python的迭代器模式

由于迭代器模式的使用太常见了,所以大多数编程语言都给常见的容器类型实现了它,例如 Java 中的 CollecTIon,List、Set、Map等。在 Java 中使用迭代器遍历 List 可这么写:

List list = new ArrayList<>();
Iterator iterator = list.iterator();
while(iterator.hasNext()){
    System.out.println(iterator.next());
}

ArrayList 类通过自身的 iterator() 方法获得一个迭代器 iterator,然后由该迭代器实例来落实遍历过程。

Python 当然也应用了迭代器模式,但它的实现思路跟上例却不太一样。

首先,Python 认为遍历容器类型并不一定要用到迭代器,因此设计了可迭代对象。

list = [1,2,3,4]
for i in list:
    print(i,end=" ") # 1 2 3 4
for i in list:
    print(i,end=" ") # 1 2 3 4

上例中的 list 是可迭代对象(Iterable),但并不是迭代器(虽然在底层实现时用了迭代器的部分思想)。Python 抓住了迭代器模式的本质,即是“迭代”,赋予了它极高的地位。

如此设计的好处显而易见:(1)写法简便,用意直白;(2)可重复迭代,避免一次性迭代器的缺陷;(3)不需要创建迭代器,减少开销。

可迭代对象可看作是广义的迭代器,同时,Python 也设计了普通意义的狭义的迭代器。

list = [1,2,3,4]
it = iter(list)
for i in it:
    print(i,end=" ") # 1 2 3 4
for i in it:
    print(i,end=" ") # 无输出

上例中的 iter() 方法会将可迭代对象变成一个迭代器。从输出结果可以看出,该迭代器的迭代过程是一次性的。

由此看来,Python 其实是将“迭代器模式”一拆为二来实现:一是可迭代思想,广泛播种于容器类型的对象中,使它们都可迭代;一是迭代器,一种特殊的可迭代对象,承担普通意义上的迭代器所特有的迭代任务。

同时,它还提供了将可迭代对象转化为迭代器的简易方法,如此安排,真是将迭代器模式的效力发挥到了极致。

(关于可迭代对象与迭代器的更多区别、以及它们的实现原理,请参见《Python进阶:迭代器与迭代器切片》)

3、创建迭代器

创建迭代器有如下方式:
(1)iter() 方法,将可迭代对象转化成迭代器;
(2)__iter__() 与 __next__() 魔术方法,定义类实现这两个魔术方法;
(3)itertools 模块,使用内置模块生成迭代器;
(4)其它创建方法,如 zip() 、map() 、enumerate() 等等。

四类方法各有适用场所,本节重点介绍 itertools 模块。它可以创建三类迭代器:无限迭代器、有限迭代器与组合迭代器。

3.1 无限迭代器

count(start=0, step=1) :创建一个从 start (默认值为 0) 开始,以 step (默认值为 1) 为步长的的无限整数迭代器。

cycle(iterable) :对可迭代对象的元素反复执行循环。

repeat(object [,TImes]) :反复生成 object 至无限,或者到给定的 TImes 次。

import itertools
co = itertools.count()
cy = itertools.cycle('ABC')
re = itertools.repeat('A', 30)

# 注意:请分别执行;以下写法未加终止判断,只能按 Ctrl+C 退出
for n in co:
    print(n,end=" ")  # 0 1 2 3 4......
for n in cy:
    print(n,end=" ")  # A B C A B C A B......
for n in re:
    print(n,end=" ")  # A A A A A A A A....(30个)

3.2 有限迭代器

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/dianzi/2474657.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-08-04
下一篇 2022-08-04

发表评论

登录后才能评论

评论列表(0条)

保存