Python中对象迭代与反迭代的技巧总结


Posted in Python onSeptember 17, 2016

一、如何实现可迭代对象和迭代器对象?

实际案例

某软件要求从网络抓取各个城市气味信息,并其次显示:

北京: 15 ~ 20 天津: 17 ~ 22 长春: 12 ~ 18 ......

如果一次抓取所有城市天气再显示,显示第一个城市气温时,有很高的延时,并且浪费存储空间,我们期望以用时访问的策略,并且把所有城市气温封装到一个对象里,可用for语句进行迭代,如何解决?

解决方案

实现一个迭代器对象Weatherlterator,next方法每次返回一个城市气温,实现一个可迭代对象Weatherlterable,————iter__方法返回一个迭代器对象

import requests from collections import Iterable, Iterator # 气温迭代器 class WeatherIterator(Iterator): def __init__(self, cities): self.cities = cities self.index = 0 def getWeather(self, city): r = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=' + city) data = r.json()['data']['forecast'][0] return '%s:%s , %s' % (city, data['low'], data['high']) def __next__(self): if self.index == len(self.cities): raise StopIteration city = self.cities[self.index] self.index += 1 return self.getWeather(city) # 可迭代对象 class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities) for x in WeatherIterable(['北京', '上海', '广州', '深圳']): print(x)

执行结果如下:

C:\Python\Python35\python.exe E:/python-intensive-training/s2.py 北京:低温 21℃ , 高温 30℃ 上海:低温 23℃ , 高温 26℃ 广州:低温 26℃ , 高温 34℃ 深圳:低温 27℃ , 高温 33℃ Process finished with exit code 0

二、如何使用生成器函数实现可迭代对象?

实际案例

实现一个可迭代对象的类,它能迭代出给定范围内所有素数:

python pn = PrimeNumbers(1, 30) for k in pn: print(k) `` 输出结果text
2 3 5 7 11 13 17 19 23 29
“`

解决方案

-将该类的__iter__方法实现生成器函数,每次yield返回一个素数

class PrimeNumbers: def __init__(self, start, stop): self.start = start self.stop = stop def isPrimeNum(self, k): if k < 2: return False for i in range(2, k): if k % i == 0: return False return True def __iter__(self): for k in range(self.start, self.stop + 1): if self.isPrimeNum(k): yield k for x in PrimeNumbers(1, 20): print(x)

运行结果

C:\Python\Python35\python.exe E:/python-intensive-training/s3.py 2 3 5 7 11 13 17 19 Process finished with exit code 0

三、如何进行反向迭代以及如何实现反向迭代?

实际案例

实现一个连续浮点数生成器FloatRange(和rrange类似),根据给定范围(start, stop)和步进值(step)产生一些列连续浮点数,如迭代FloatRange(3.0,4.0,0.2)可产生序列:

正向:3.0 > 3.2 > 3.4 > 3.6 > 3.8 > 4.0 反向:4.0 > 3.8 > 3.6 > 3.4 > 3.2 > 3.0

解决方案

实现反向迭代协议的__reversed__方法,它返回一个反向迭代器

class FloatRange: def __init__(self, start, stop, step=0.1): self.start = start self.stop = stop self.step = step def __iter__(self): t = self.start while t <= self.stop: yield t t += self.step def __reversed__(self): t = self.stop while t >= self.start: yield t t -= self.step print("正相迭代-----") for n in FloatRange(1.0, 4.0, 0.5): print(n) print("反迭代-----") for x in reversed(FloatRange(1.0, 4.0, 0.5)): print(x)

输出结果

C:\Python\Python35\python.exe E:/python-intensive-training/s4.py 正相迭代----- 1.0 1.5 2.0 2.5 3.0 3.5 4.0 反迭代----- 4.0 3.5 3.0 2.5 2.0 1.5 1.0 Process finished with exit code 0

四、如何对迭代器做切片操作?

实际案例

有某个文本文件,我们想都去其中某范围的内容,如100~300行之间的内容,python中文本文件是可迭代对象,我们是否可以使用类似列表切片的方式得到一个100~300行文件内容的生成器?

解决方案

使用标准库中的itertools.islice,它能返回一个迭代器对象切片的生成器

from itertools import islice f = open('access.log') # # 前500行 # islice(f, 500) # # 100行以后的 # islice(f, 100, None) for line in islice(f,100,300): print(line)

islice每次训话都会消耗之前的迭代对象

l = range(20) t = iter(l) for x in islice(t, 5, 10): print(x) print('第二次迭代') for x in t: print(x)

输出结果

C:\Python\Python35\python.exe E:/python-intensive-training/s5.py 5 6 7 8 9 第二次迭代 10 11 12 13 14 15 16 17 18 19 Process finished with exit code 0

五、如何在一个for语句中迭代多个可迭代对象?

实际案例

1、某班学生期末考试成绩,语文、数学、英语分别存储再3个列表中,同时迭代三个列表,计算每个学生的总分(并行)

2、某年纪有四个班,某次考试没班英语成绩分别存储在四个列表中,依次迭代每个列表,统计全学年成绩高于90分人数(串行)

解决方案

并行:使用内置函数zip,它能将多个可迭代对象合并,每次迭代返回一个元组

from random import randint # 申城语文成绩,# 40人,分数再60-100之间 chinese = [randint(60, 100) for _ in range(40)] math = [randint(60, 100) for _ in range(40)] # 数学 english = [randint(60, 100) for _ in range(40)] # 英语 total = [] for c, m, e in zip(chinese, math, english): total.append(c + m + e) print(total)

执行结果如下:

C:\Python\Python35\python.exe E:/python-intensive-training/s6.py [232, 234, 259, 248, 241, 236, 245, 253, 275, 238, 240, 239, 283, 256, 232, 224, 201, 255, 206, 239, 254, 216, 287, 268, 235, 223, 289, 221, 266, 222, 231, 240, 226, 235, 255, 232, 235, 250, 241, 225] Process finished with exit code 0

串行:使用标准库中的itertools.chain,它能将多个可迭代对象连接

from random import randint from itertools import chain # 生成四个班的随机成绩 e1 = [randint(60, 100) for _ in range(40)] e2 = [randint(60, 100) for _ in range(42)] e3 = [randint(60, 100) for _ in range(45)] e4 = [randint(60, 100) for _ in range(50)] # 默认人数=1 count = 0 for s in chain(e1, e2, e3, e4): # 如果当前分数大于90,就让count+1 if s > 90: count += 1 print(count)

输出结果

C:\Python\Python35\python.exe E:/python-intensive-training/s6.py 48 Process finished with exit code 0

总结

以上就是这篇文章的全部内容,希望对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。

Python 相关文章推荐
python模块之StringIO使用示例
Apr 08 Python
深入理解Python中各种方法的运作原理
Jun 15 Python
Python何时应该使用Lambda函数
Jul 02 Python
Python进程,多进程,获取进程id,给子进程传递参数操作示例
Oct 11 Python
python使用openCV遍历文件夹里所有视频文件并保存成图片
Jan 14 Python
浅谈matplotlib.pyplot与axes的关系
Mar 06 Python
django项目中新增app的2种实现方法
Apr 01 Python
浅谈keras保存模型中的save()和save_weights()区别
May 21 Python
Django Session和Cookie分别实现记住用户登录状态操作
Jul 02 Python
Python列表推导式实现代码实例
Sep 09 Python
pycharm-professional-2020.1下载与激活的教程
Sep 21 Python
如何使用pycharm连接Databricks的步骤详解
Sep 23 Python
发布你的Python模块详解
Sep 15 #Python
Python selenium 三种等待方式解读
Sep 15 #Python
玩转python selenium鼠标键盘操作(ActionChains)
Apr 12 #Python
Python selenium文件上传方法汇总
Nov 19 #Python
Python selenium如何设置等待时间
Sep 15 #Python
Python selenium 父子、兄弟、相邻节点定位方式详解
Sep 15 #Python
Python selenium 三种等待方式详解(必会)
Sep 15 #Python
You might like
PHP安全防范技巧分享
2011/11/03 PHP
PHP中round()函数对浮点数进行四舍五入的方法
2014/11/19 PHP
php计划任务之ignore_user_abort函数实现方法
2015/01/08 PHP
php 读取输出其他文件的实现方法
2016/07/26 PHP
document.designMode的功能与使用方法介绍
2007/11/22 Javascript
document.compatMode介绍
2009/05/21 Javascript
EXTJS内使用ACTIVEX控件引起崩溃问题的解决方法
2010/03/31 Javascript
js TextArea的选中区域处理
2010/12/28 Javascript
JS Range HTML文档/文字内容选中、库及应用介绍
2011/05/12 Javascript
jquery中each方法示例和常用选择器
2014/07/08 Javascript
javascript正则表达式中的replace方法详解
2015/04/20 Javascript
详解JavaScript中shift()方法的使用
2015/06/09 Javascript
JS实现可点击展开与关闭的左侧广告代码
2015/09/02 Javascript
详解BootStrap中Affix控件的使用及保持布局的美观的方法
2016/07/08 Javascript
vue.js初学入门教程(1)
2016/11/03 Javascript
微信小程序scroll-view组件实现滚动动画
2018/01/31 Javascript
js捆绑TypeScript声明文件的方法教程
2018/04/13 Javascript
Angular-UI Bootstrap组件实现警报功能
2018/07/16 Javascript
ES6入门教程之变量的解构赋值详解
2019/04/13 Javascript
详解微信小程序-canvas绘制文字实现自动换行
2019/04/26 Javascript
ES6学习笔记之字符串、数组、对象、函数新增知识点实例分析
2020/01/22 Javascript
JavaScript JSON使用原理及注意事项
2020/07/30 Javascript
深入学习python的yield和generator
2016/03/10 Python
Python3简单实例计算同花的概率代码
2017/12/06 Python
Python中if elif else及缩进的使用简述
2018/05/31 Python
python socket 聊天室实例代码详解
2019/11/14 Python
最新2019Pycharm安装教程 亲测
2020/02/28 Python
Python识别验证码的实现示例
2020/09/30 Python
Armor Lux法国官方网站:水手服装、成衣和内衣
2020/05/26 全球购物
德国高尔夫商店:Par71.de
2020/11/29 全球购物
8和9的加减法教学反思
2014/05/01 职场文书
青安岗事迹材料
2014/05/14 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
创业计划书之o2o水果店
2019/08/30 职场文书
导游词之苏州阳澄湖
2019/11/15 职场文书
浅析Redis Sentinel 与 Redis Cluster
2021/06/24 Redis