侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python 迭代器与生成器实例详解

Python  /  管理员 发布于 7年前   163

Python 迭代器与生成器实例详解

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

1.由可迭代对象得到迭代器对象

例如l就是可迭代对象,iter(l)是迭代器对象

In [1]: l = [1,2,3,4]In [2]: l.__iter__Out[2]: <method-wrapper '__iter__' of list object at 0x000000000426C7C8>In [3]: t = iter(l)In [4]: t.next()Out[4]: 1In [5]: t.next()Out[5]: 2In [6]: t.next()Out[6]: 3In [7]: t.next()Out[7]: 4In [8]: t.next()---------------------------------------------------------------------------StopIteration   Traceback (most recent call last)<ipython-input-8-3660e2a3d509> in <module>()----> 1 t.next()StopIteration:for x in l:  print xfor 循环的工作流程,就是先有iter(l)得到一个t,然后不停的调用t.nex(),到最后捕获到StopIteration,就结束迭代

# 下面这种直接调用函数的方法如果数据量大的时候会对网络IO要求比较高,可以采用迭代器的方法

def getWeather(city):  r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city='+city)  data = r.json()['data']['forecast'][0]  return '%s:%s,%s' %(city, data['low'], data['high'])print getWeather(u'北京')返回值:
北京:低温 13℃,高温 28℃

实现一个迭代器对象WeatherIterator,next 方法每次返回一个城市气温

实现一个可迭代对象WeatherIterable,iter方法返回一个迭代器对象

# -*- coding:utf-8 -*-import requestsfrom collections import Iterable, Iteratorclass WeatherIterator(Iterator):  def __init__(self, cities):    self.cities = cities    self.index = 0  def getWeather(self,city):    r = requests.get(u'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([u'北京',u'上海',u'广州',u'深圳']):  print x.encode('utf-8')输出:北京:低温 13℃,高温 28℃上海:低温 14℃,高温 22℃广州:低温 17℃,高温 23℃深圳:低温 18℃,高温 24℃

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

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

素数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为素数。

一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

class PrimeNumbers:  def __init__(self, start, end):    self.start = start    self.end = end  def isPrimeNum(self, k):    if k < 2:      return False    for i in xrange(2, k):      if k % i == 0:        return False    return True  def __iter__(self):    for k in xrange(self.start, self.end + 1):      if self.isPrimeNum(k):        yield kfor x in PrimeNumbers(1, 10):  print x输出:2357

三、实现反向迭代

1.反向进行迭代

例如: 实现一个浮点数发生器FloatRange(和xrange类似),根据给定范围(start, end)和步径值(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

class FloatRange:  def __init__(self, start, end, step=0.1):    self.start = start    self.end = end    self.step = step  def __iter__(self):    t = self.start    while round(t,14) <= round(self.end, 14):      yield t      t = t + self.step  def __reversed__(self):    t = self.end    while round(t, 14) >= round(self.start, 14):      yield t      t = t - self.stepfor x in reversed(FloatRange(3.0, 4.0, 0.2)):  print x输出:4.03.83.63.43.23.0for x in FloatRange(3.0, 4.0, 0.2):
    print x
输出:
3.0
3.2
3.4
3.6
3.8
4.0

上面代码采用round函数是因为浮点数比较会有精度问题,所以需要进行四舍五入

2.对迭代器进行切片操作

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

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

f = open('/var/log/dmesg')from itertools import islice# 对文件内容100到300行之间进行切片,返回的是个生成器对象,默认i径是1islice(f, 100, 300)# 前500行内容islice(f, 500)# 100行到末尾结束内容islice(f, 100, None)ps: 每次使用islice要重新申请对象,它会消耗原来的迭代对象

四、 迭代多个对象

1.在一个for语句中迭代多个可迭代对象

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

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

解决方案:

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

from random import randintchinese = [randint(60,100) for _ in xrange(40)]math = [randint(60,100) for _ in xrange(40)]english = [randint(60,100) for _ in xrange(40)]total = []for c,m,e in zip(chinese, math,english):  total.append(c+m+e)print total输出:[204, 227, 238, 201, 227, 205, 251, 274, 210, 242, 220, 239, 237, 207, 230, 267, 263, 240, 247, 249, 255, 268, 209, 270, 259, 251, 245, 262, 234, 221, 236, 250, 251, 249, 242, 255, 232, 272, 237, 253]

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

from random import randintfrom itertools import chainclass1 = [randint(60,100) for _ in xrange(40)]class2 = [randint(60,100) for _ in xrange(42)]class3 = [randint(60,100) for _ in xrange(39)]class4 = [randint(60,100) for _ in xrange(43)]count = 0for s in chain(class1, class2, class3, class4):  if s > 90:    count = count + 1print count输出:38

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


  • 上一条:
    Python操作MongoDB详解及实例
    下一条:
    Python字符串处理实例详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客