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

发布时间 - 2026-01-11 01:09:38    点击率:

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]: 1

In [5]: t.next()
Out[5]: 2

In [6]: t.next()
Out[6]: 3

In [7]: t.next()
Out[7]: 4

In [8]: t.next()
---------------------------------------------------------------------------
StopIteration               Traceback (most recent call last)
<ipython-input-8-3660e2a3d509> in <module>()
----> 1 t.next()

StopIteration:

for x in l:
  print x
for 循环的工作流程,就是先有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 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(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 k

for x in PrimeNumbers(1, 10):
  print x

输出:
2
3
5
7

三、实现反向迭代

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.step

for x in reversed(FloatRange(3.0, 4.0, 0.2)):
  print x
输出:
4.0
3.8
3.6
3.4
3.2
3.0
for 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行之间进行切片,返回的是个生成器对象,默认歩径是1
islice(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 randint

chinese = [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 randint
from itertools import chain

class1 = [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 = 0
for s in chain(class1, class2, class3, class4):
  if s > 90:
    count = count + 1

print count

输出:
38


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


# Python  # 迭代器与生成器  # 迭代器与生成器使用方法  # 深入讲解Python中的迭代器和生成器  # python的迭代器与生成器实例详解  # 举例讲解Python中的迭代器、生成器与列表解析用法  # 解析Python中的生成器及其与迭代器的差异  # 老生常谈Python之装饰器、迭代器和生成器  # 详解Python3中的迭代器和生成器及其区别  # 详解Python的迭代器、生成器以及相关的itertools包  # python生成器  # 可迭代对象  # 迭代器区别和联系  # 浅谈Python中的可迭代对象、迭代器、For循环工作机制、生成器  # Python学习笔记之迭代器和生成器用法实例详解  # 迭代  # 多个  # 北京  # 英语  # 广州  # 能将  # 浮点数  # 深圳  # 它能  # 上海  # 文本文件  # 行之  # 库中  # 就会  # 是个  # 会有  # 是因为  # 列表中  # 较高  # 对其 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  微信小程序 require机制详解及实例代码  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  如何挑选最适合建站的高性能VPS主机?  Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】  HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】  创业网站制作流程,创业网站可靠吗?  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  如何在IIS服务器上快速部署高效网站?  php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】  百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧  如何快速搭建高效香港服务器网站?  安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出  Laravel如何处理表单验证?(Requests代码示例)  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  原生JS获取元素集合的子元素宽度实例  悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID  Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程  Laravel怎么在Blade中安全地输出原始HTML内容  HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】  PHP 500报错的快速解决方法  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  JS弹性运动实现方法分析  JS中页面与页面之间超链接跳转中文乱码问题的解决办法  JavaScript中如何操作剪贴板_ClipboardAPI怎么用  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  详解Android图表 MPAndroidChart折线图  Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】  ,网页ppt怎么弄成自己的ppt?  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  JavaScript如何实现音频处理_Web Audio API如何工作?  ,怎么在广州志愿者网站注册?  高性能网站服务器配置指南:安全稳定与高效建站核心方案  Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用  郑州企业网站制作公司,郑州招聘网站有哪些?  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  如何基于PHP生成高效IDC网络公司建站源码?  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】  Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】  微信小程序 五星评分(包括半颗星评分)实例代码  JavaScript中的标签模板是什么_它如何扩展字符串功能  成都网站制作公司哪家好,四川省职工服务网是做什么用?  网页设计与网站制作内容,怎样注册网站?  在Oracle关闭情况下如何修改spfile的参数  IOS倒计时设置UIButton标题title的抖动问题