文档章节

Python迭代器与生成器

听风的小猪
 听风的小猪
发布于 2017/05/02 14:27
字数 1437
阅读 551
收藏 33

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

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

© 著作权归作者所有

共有 人打赏支持
听风的小猪

听风的小猪

粉丝 69
博文 39
码字总数 35907
作品 0
黄浦
程序员
私信 提问
Python3+迭代器与生成器

转载Python3 迭代器与生成器 迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式。 迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的...

xinet
2017/08/12
0
0
Python3基础之学习笔记(五)-装饰器-迭代器和生成器-内置函数

文章目录 1.装饰器 2.迭代器与生成器 3.迭代器 4.内置函数 1.装饰器 1.1装饰器简介 装饰器本质是函数,是用来装饰其他函数的,为其他函数添加附件功能 原则: 不能修改被装饰的函数的源代码 ...

GoldenKitten
01/15
0
0
Python3 迭代器与生成器

迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式。 迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只...

Eappo_Geng
2018/04/05
0
0
Python知识点总结篇(四)

递归 特性 - 必须有明确的结束条件; - 每进入深一层递归,问题规模比上层应有所减少; 递归效率不高,层次更多会导致栈溢出; 函数式编程 计算机:在计算机层面,CPU执行的是加减乘除以及各...

村雨1943
2018/10/03
0
0
Python中的迭代器与生成器

container.iter() 和 iterator.next() 迭代器就是一个有 next() 方法的对象。当需要下一个数据时,调用它的 next() 方法就可以获得。在Python2中,这个方法被命名为 next() 。但在Python3中新...

lionets
2013/11/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

商品详情页上拉查看详情

商品详情页上拉查看详情 目录介绍 01.该库介绍 02.效果展示 03.如何使用 04.注意要点 05.优化问题 06.部分代码逻辑 07.参考案例 01.该库介绍 模仿淘宝、京东、考拉等商品详情页分页加载的UI效...

潇湘剑雨
20分钟前
0
0
Netty内存池之PoolArena详解

PoolArena是Netty内存池中的一个核心容器,它的主要作用是对创建的一系列的PoolChunk和PoolSubpage进行管理,根据申请的不同内存大小将最终的申请动作委托给这两个子容器进行管理。整体上,P...

爱宝贝丶
25分钟前
1
0
Django使用Channels实现WebSocket--下篇

希望通过对这两篇文章的学习,能够对Channels有更加深入的了解,使用起来得心应手游刃有余 通过上一篇《Django使用Channels实现WebSocket--上篇》的学习应该对Channels的各种概念有了清晰的认...

运维咖啡吧
32分钟前
2
0
linux下设置定时执行shell脚本的示例

很多时候我们有希望服务器定时去运行一个脚本来触发一个操作,比如说定时去备份服务器数据、数据库数据等 不适合人工经常做的一些操作这里简单说下 shell Shell俗称壳,类似于DOS下的command...

阿锋zxf
35分钟前
3
0
介绍Kubernetes监控Heapster

什么是Heapster? Heapster是容器集群监控和性能分析工具,天然的支持Kubernetes和CoreOS,Kubernetes有个出名的监控agent—cAdvisor。在每个kubernetes Node上都会运行cAdvisor,它会收集本机...

xiangyunyan
37分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部