【Python】生成器和迭代器
l=[1,2,3,4] for n in l:
print n
在看上面这段代码的时候,我们没有显式的控制列表的偏移量,就可以自动的遍历了整个列表对象。那么for 语句是怎么来遍历列表l的呢?要回答这个问题,我们必须首先来看一下迭代器相关的知识。
迭代器
迭代器对象要求支持迭代器协议,所谓支持迭代器协议就是对象包含__iter__()和next()方法。其中__iter__()方法返回迭代器对象自己;next()方法返回下一个前进到下一个结果,在结尾时引发StopIteration异常。
列表不是迭代器对象,但是列表通过__iter__()可以得到一个迭代器对象来遍历整个列表的内容,像列表这样的序列对象都属于这种情况;与序列不同,文件对象本身就是一种迭代器对象。
l=[1,2,3,4]
f=open('test.c','r') iter(l) == l
Out[131]: False iter (f)== f
Out[132]: True
一个迭代器的例子:
class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def next(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
2.生成器
生成器使python可以很容易的支持迭代协议。生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yeild一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
3.for语句如何工作
在我们最前面的遍历列表的for语句中,for使用了列表支持迭代器的性质,可以每次通过调用迭代器的next()方法,来遍历到列表中的值,直到遇到StopIteration的异常。
4.迭代器、列表解析、生成器的分析比较
- 迭代器(iterator)
迭代器用来为类序列对象提供一个类序列的接口。迭代器就是生成一个有next()方法的对象,而不是通过索引来计数。
序列、字典、文件中当使用for x in y的结构时,其实质就是迭代器,迭代器是和实际对象绑定在一起的,所以在使用迭代器时或者上述3者时不能修改可变对象的值。这会产生错误。如:在使用for x in y的结构来遍历字典时删除符合条件的字典内容,这会导致报错。
创建迭代器的方法:iter(object)和iter(func,sentinel)两种。一种使用的是序列,另一种使用类来创建。
- 列表解析(List comprehensions)
主要用来动态的创建列表,和map()、filter()和reduce()一样可以用来产生列表。和生成器不同的是,列表解析一次生成一个列表,所占内存较大。
列表解析的扩展版本语法:[expr for iter_var in iterable if cond_expr]
- 生成器
生成器是特定的函数,允许你返回一个值,然后“暂停”代码的执行,稍后恢复。生成器使用了“延迟计算”,所以在内存上面更加有效。
生成器表达式:(expr for iter_var in iterable if cond_expr)
练习:使用文件读取,找出文件中最长的行的。最精简答案:max(len(x.strip()) for x in open('/etc/motd','r'))
【Python】生成器和迭代器的更多相关文章
- python 生成器和迭代器有这篇就够了
本节主要记录一下列表生成式,生成器和迭代器的知识点 列表生成器 首先举个例子 现在有个需求,看列表 [0,1,2,3,4,5,6,7,8,9],要求你把列表里面的每个值加1,你怎么实现呢? 方法一(简 ...
- 【转】python 生成器和迭代器有这篇就够了
总结得特别好,转自:https://www.cnblogs.com/wj-1314/p/8490822.html 本节主要记录一下列表生成式,生成器和迭代器的知识点 列表生成器 首先举个例子 现在有个 ...
- Python 生成器 (generator) & 迭代器 (iterator)
python 生成器 & 迭代器 生成器 (generator) 列表生成式 列表生成式用来生成一个列表,虽然写的是表达式,但是储存的是计算出来的结果,因此生成的列表受到内存大小的限制 示例: ...
- python 生成器,迭代器,闭包,装饰器
1.生成器,迭代器,闭包,装饰器的优点 生成器就是一类特殊的迭代器 迭代器的优点也即生成器的优点: 1.节约内存.python在使用生成器时对延迟操作提供了支持. 2.迭代到下一次的调用时,所使用的参 ...
- Python 生成器与迭代器 yield 案例分析
前几天刚开始看 Python ,后因为项目突然到来,导致Python的学习搁置了几天.然后今天看回Python 发现 Yield 这个忽然想不起是干嘛用的了(所以,好记性不如烂笔头.).然后只能 花点 ...
- Python生成器、迭代器、可迭代对象
把一个列表[]改成()就创建了一个生成器:generator,generator保存的是算法. 可以用于for循环的数据类型:1.集合类型:list tuple dict set str2.gener ...
- python 生成器和迭代器
迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stoplteration异常,以终止迭代(只能往后走不能往前退) 2.可迭代对象:实现了 ...
- Python生成器,迭代器,可迭代对象
在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...
- python 生成器和迭代器介绍
在正式接触生成器之前,我们先来了解一些概念 容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个迭代获取,可以用in.not in关键字判断元素是否包含在容器中. ...
- python 生成器与迭代器(yield 用法)
背景 首先,我不会解释这两个名词,我看过很多遍解释,可还是看不懂,还是直接看使用情景吧. 我们以佩波拉契数列为例,当我们不知道迭代器的情况下,我们写出来的代码可能是这样子的: '''这种方式计算fib ...
随机推荐
- tpot从elastic search拉攻击数据之三 用于拉取的java程序
package download; import org.json.JSONArray; import java.io.*; import java.net.URL; import java.net. ...
- session补充
- 使用jQuery重用form表单并异步提交到其它action
在做页面开发的时候,有时候要重用表单的数据,并异步请求提交到其它的链接中,这个时候就能够使用jquery去改动表单的action值(记得使用后改动回来).并调用submit方法,当然后台的链接acti ...
- spring-知识小结之注解为属性赋值
<1>.本类中的属性赋值 public class UserServiceImpl implements UserService { //按照类别赋值 // @Autowired //按照 ...
- Jquery 实现跨域处理
JS部分代码: $.ajax({ url:url, dataType:'jsonp', data:{title:title}, jsonp:'callback', success:function(l ...
- php RFC兼容的电子邮件地址验证
php中,进行RFC兼容的电子邮件地址验证的方法,有需要的朋友参考下吧. 分享一个可以验证RFC兼容的电子邮件地址的代码,支持RFC1123,2396,3696,4291,4343,5321等的验证. ...
- 102. Binary Tree Level Order Traversal ------层序遍历
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to righ ...
- redis 笔记05 Sentinel、集群
Sentinel 1. Sentinel只是一个运行在特殊模式下的Redis服务器,它使用了和普通模式不同的命令表,所以Sentinel模式能够使用的命令和普通的Redis服务器能够使用的命令不同. ...
- Linux中read命令的用法—(6/30)
read命令是一个非常重要的bash命令,用于从键盘或者表中输入中文本,并且可以和用户进行交互:该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开.在read命令后面,如果没有指定变量名 ...
- 【Flask】Flask常用信号
使用信号分为3步,第一是定义一个信号,第二是监听一个信号,第三是发送一个信号. 1. 定义信号:定义信号需要使用到blinker这个包的Namespace类来创建一个命名空间.比如定义一个在访问了某个 ...