Python进阶:设计模式之迭代器模式

纯方位无源定位的三圆共点建模与MATLAB工程实现 纯方位无源定位是一种仅依赖角度测量、不依赖距离信息的被动定位技术,其数学本质是利用‘定角对定边’几何原理,将接收机约束在以发射机基线为弦的圆弧轨迹上;当引入三组独立方位角时,对应三条圆弧理论上交于唯一一点,即‘三圆共点’——这是实现高精度定位的核心前提。该模型的技术价值在于规避电磁辐射、适配无人机编队等强干扰场景,广泛应用于无源侦察、协同导航与抗干扰飞行控制。实际落地难点在于将理想几何关系转化为可计算、可验证、抗误差的数值求解流程,尤其涉及坐标系统一、角度单位制(deg)严格管控、多解筛选及延长线退化判定等 阅读详情

点击上方“编程派”,选择设为“设为星标”

优质文章,第一时间送达!

作者:豌豆花下猫

来自:Python猫 

链接:https://mp.weixin.qq.com/s/7MbRCn37fIIN42rLm6ho3g

在软件开发领域中,人们经常会用到这一个概念——“设计模式”(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<String> list = new ArrayList<>();
Iterator<String> 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 其实是将“迭代器模式”一拆为二来实现:一是可迭代思想,广泛播种于容器类型的对象中,使它们都可迭代;一是迭代器,一种特殊的可迭代对象,承担普通意义上的迭代器所特有的迭代任务。

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

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 有限迭代器

以上方法,比较常用的有:chain() 将多个可迭代对象(可以是不同类型)连接成一个大迭代器;compress() 方法根据真假过滤器筛选元素;groupby() 把迭代器中相邻的重复元素挑出来放在一起;islice() 方法返回迭代器切片;tee() 方法根据可迭代对象创建 n 个(默认2个)迭代器副本。

for c in itertools.chain('ABC', [1,2,3]):
    print(c,end=" ")
# 输出结果:A B C 1 2 3

for c in itertools.compress('ABCDEF', [1, 1, 0, 1, 0, 1]):
    print(c,end=" ")
# 输出结果:A B D F

for key, group in itertools.groupby('aaabbbaaccd'):
    print(key, ':', list(group))
# 输出结果:
a : ['a', 'a', 'a']
b : ['b', 'b', 'b']
a : ['a', 'a']
c : ['c', 'c']
d : ['d']

itertools.tee('abc', 3)
# 输出结果:(<itertools._tee at 0x1fc72c08108>,
 <itertools._tee at 0x1fc73f91d08>,
 <itertools._tee at 0x1fc73efc248>)

3.3 组合迭代器

product() :求解多个可迭代对象的笛卡尔积。

permutations() :求解可迭代对象的元素的排列。

combinations():求解可迭代对象的元素的组合。

for i in itertools.product('ABC', [1,2]):
    print(i, end=" ")
# 输出结果:('A', 1) ('A', 2) ('B', 1) ('B', 2) ('C', 1) ('C', 2)

for i in itertools.permutations('ABC', 2):
    print(i, end=" ")
# 输出结果:('A', 'B') ('A', 'C') ('B', 'A') ('B', 'C') ('C', 'A') ('C', 'B')

for i in itertools.combinations('ABC', 2):
    print(i, end=" ")
# 输出结果:('A', 'B') ('A', 'C') ('B', 'C')

for i in itertools.combinations('ABCD', 3):
    print(i, end=" ")
# 输出结果:('A', 'B', 'C') ('A', 'B', 'D') ('A', 'C', 'D') ('B', 'C', 'D')

4、强大的内置迭代器方法

迭代器模式的使用场景实在太普遍了,而 Python 也为迭代器的顺利使用而提供了很多便利的条件,本节将介绍相关的几个内置方法。这些方法非常常用而且强大,是 Python 进阶的必会内容。

4.1 zip() 方法

zip() 方法可以同时迭代多个序列,并各取一个元素,生成一个可返回元组的迭代器。此迭代器的长度以较短序列的长度保持一致,若想生成较长序列的长度,需要使用 itertools 模块的 zip_longest() 方法。

import itertools

a = [1, 2, 3]
b = ['w', 'x', 'y', 'z']

for i in zip(a,b):
    print(i,end=" ")  # (1, 'w') (2, 'x') (3, 'y')

# 空缺值以 None 填补
for i in itertools.zip_longest(a,b):
    print(i,end=" ")  # (1, 'w') (2, 'x') (3, 'y') (None, 'z')

4.2 enumerate() 方法

enumerate() 方法接收一个序列类型参数,生成一个可返回元组的迭代器,元组内容是下标及其对应的元素值。它还可接收一个可选参数,指定下标的起始值,默认是0 。

注意:众所周知,Python 中序列的索引值从 0 开始,但是,enumerate() 可以达到改变起始索引数值的效果。

seasons = ['Spring', 'Summer', 'Fall', 'Winter']

for i in enumerate(seasons):
    print(i,end=" ")  
#输出结果:(0, 'Spring') (1, 'Summer') (2, 'Fall') (3, 'Winter')

for i in enumerate(seasons, start=7):
    print(i,end=" ")  
#输出结果:(7, 'Spring') (8, 'Summer') (9, 'Fall') (10, 'Winter')

4.3 map() 方法

map() 方法的参数是一个函数及一个或多个可迭代对象,它会将可迭代对象的元素映射到该函数中,然后迭代地运行该函数,返回结果也是一个迭代器。当存在多个可迭代对象参数时,迭代长度等于较短对象的长度。

def square(x):
    return x ** 2

l = map(square, [1, 2, 3, 4, 5])
print(list(l))
# 输出结果:[1, 4, 9, 16, 25]

m = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10, 2])
print(list(m))
# 输出结果:[3, 7, 11, 15, 19]

4.4 filter() 方法

filter() 方法的参数是一个判断函数及一个可迭代对象,遍历可迭代对象执行判断函数,过滤下判断为True 的元素,与它相对,若想保留判断为 False 的元素,可使用 itertoole 模块的 filterfalse() 方法。

import itertools

fi = filter(lambda x: x%2, range(10))
ff = itertools.filterfalse(lambda x: x%2, range(10))

for i in fi:
    print(i,end=" ")
# 输出结果:1 3 5 7 9

for i in ff:
    print(i,end=" ")
# 输出结果:0 2 4 6 8

5. 小结

迭代器模式几乎是 23 种设计模式中最常用的设计模式,本文主要介绍了 Python 是如何运用迭代器模式,并介绍了 itertools 模块生成迭代器的 18 种方法,以及 5 种生成迭代器的内置方法。

回复下方「关键词」,获取优质资源

回复关键词「 pybook03」,立即获取主页君与小伙伴一起翻译的《Think Python 2e》电子版
回复关键词「入门资料」,立即获取主页君整理的 10 本 Python 入门书的电子版
回复关键词「m」,立即获取Python精选优质文章合集
回复关键词「book 数字」,将数字替换成 0 及以上数字,有惊喜好礼哦~
题图:pexels,CC0 授权。

好文章,我在看❤️

避坑指南:OpenWebUI+SearXNG联网搜索的5个常见配置错误及解决方法 本文详细解析了OpenWebUI与SearXNG整合过程中常见的5个配置错误及解决方案,包括JSON格式配置陷阱、国内搜索引擎缺失、连续搜索失效等问题。通过实战验证的优化策略,帮助开发者避免性能下降和功能异常,提升大模型与搜索引擎的协同效率。 阅读详情

相关推荐

STM32-DAC定时器触发三角波生成【频率与幅度精准控制】

本文详细介绍了STM32 DAC定时器触发三角波生成的原理与实现方法,涵盖硬件配置、频率与幅度精准控制技巧及代码实现。通过定时器触发DAC模块,可灵活调节三角波的频率和幅度,适用于信号发生器等高精度应用场景。

weixin_29161785的博客 452

JAVA复习【13】Map的三种遍历方法

Map的三种遍历方法

qq_44956118的博客 5905

【AI实践】Dify调用本地和在线模型服务

Ollama可以本地部署模型,如何集成私有数据、如何外部应用程序对接,因此需要有一个应用开发框架。ip地址需要换成自己电脑的IP地址;模型名称需要和Ollama模型名称保持一致;docker是虚拟环境的主机,Ollama部署在本地主机,无法通过本机访问。找到Ollama,配置本地Ollama已经验证的模型,如phi3。在docker页面里面,也可以看到running。docker已经安装完成的情况下。,打开dify,注册登录后。在工作区选择调用即可。

AI_Gump的博客 4854

Map常用的两种遍历方式

一、迭代器遍历 通过key的值获取value。 Map<Integer, String> map = new HashMap<Integer, String>(); map.put(1, "张三"); map.put(2, "李四"); map.put(3, "王五"); Set<Integer> keySet = map.keySet(); // 获取map所有的key成新的集合 System.out.println(keySet); /...

i1103的博客 3501

MATLAB仿真实战:双有源桥(DAB)变换器的扩展移相调制(EPS)全流程解析

本文提供了一份详细的MATLAB/Simulink仿真实战指南,手把手解析双有源桥(DAB)变换器在扩展移相调制(EPS)下的全流程建模。内容涵盖从核心原理、主功率电路搭建、EPS驱动信号生成,到仿真运行、波形分析及模型优化的完整步骤,旨在帮助工程师和研究者快速掌握DAB变换器的仿真与性能验证方法。

o4p5q6r7s的博客 503

Unity技术开发干货 - 总目录

总目录 欢迎大家来到 passion 的《Unity技术开发干货》开始前博主先列出学习的大纲,同时也供大家学习参考,如果有什么问题,欢迎留言。 一.Unity基础: Unity基础-脚本生命周期 Unity基础-向量 Unity基础-寻路系统 Unity基础-物理系统 Unity基础-Mecanim动画系统 Unity基础-UGUI Unity基础-灯光 Unity-UGUI之Event System Unity-2018-粒子系统 Unity-协程入门 Unity-2D物理引擎、铰链、效应器 Unity-

TxNet 4257

Iterator遍历,迭代Map集合的三种方式

使用Iterator遍历,迭代Map集合的三种方式

just_learing的博客 5491

使用MATLAB的COMSOL LiveLink:实时连接和数据传输

COMSOL LiveLink是一种功能强大的MATLAB工具包,它允许用户在MATLAB环境中与COMSOL Multiphysics软件进行实时连接和数据传输。COMSOL LiveLink是一种功能强大的MATLAB工具包,它允许用户在MATLAB环境中与COMSOL Multiphysics软件进行实时连接和数据传输。使用COMSOL LiveLink,你可以进行更复杂的模型设置和数据传输使用MATLAB的COMSOL LiveLink:实时连接和数据传输。

PixelNinja的博客 2088

Map的6种遍历方式

介绍了遍历Map的六种方法,和其中两种常用又美观的方式。

qq_52430605的博客 3万+

2023年下半年网络工程师案例分析真题答案解析

R1] ip route-static 0.0.0.0 0.0.0.0 GigabitEthemet2/0/1 (3) track (4) R1 to R2 //配置R1的缺省路由,联动BFD使得R1到2的流量优先走R1->S1->R2链路,当此链路发生故障时,流量切换到R1->R3->R2链路上。当同一VLAN内也需要网络隔离时,我们可采用交换机的(2)功能,若在配置了二层隔离后,部分主机有互通的需求,则可在需求主机的网关上配置(3)功能。不需要,MAC地址是数据链路层封装以太帧的地址标识。

鹿鸣天涯 748

PyTorch实战(14)——图注意力网络(Graph Attention Network,GAT)

本节介绍了图注意力网络 (Graph Attention Network, GAT) 在节点分类任务中的应用。相比图卷积网络 (GCN) 的平均聚合机制,GAT 通过引入注意力机制,能够为不同邻居节点分配差异化权重,从而更精准地捕捉图结构信息。实验表明,GAT 在 CiteSeer 数据集上的分类准确率达到 71.1%,较 GCN 提升 2.5 个百分点。可视化结果显示,GAT 学习到的节点表征具有更好的类别区分度。这验证了注意力机制在图数据建模中的有效性,为处理复杂图结构任务提供了更优解决方案。

盼小辉丶的博客 3537

Python 进阶:设计模式之迭代器模式

(给Python开发者加星标,提升Python技能)作者:豌豆花下猫 (本文来自作者投稿)在软件开发领域中,人们经常会用到这一个概念——“设计模式”(design pat...

Python开发者 343

【深度学习|学习笔记】广义线性模型Generalized linear model(GLM)模型详解,附代码。

【深度学习|学习笔记】广义线性模型Generalized linear model(GLM)模型详解,附代码。

2401_89898861的博客 1871

[转载] Python进阶:设计模式之迭代器模式

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

ld909的博客 103

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: 一站配齐所有国内镜像,第三方库安装提升 10 倍
下一篇: 有了这个免费的全家桶,你的 Mac 隐私安全不再是问题了
codingpy
博客等级 码龄11年 1867粉丝 104原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值