python基础 生成器 迭代器
列表生成式:
a=[1,2,3]
print a
b=[i*2 for i in range(10)] #i循环10次,每一个i的值乘2就是列表中的值。列表生成式
print b
>>[1, 2, 3]
>>[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
生成器:
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
b=(i*2 for i in range(10)) #将生成列表中的[]转换成(),就是一个生成器。
print b
生成器与列表的区别:
列表在定义的时候,已经在内存中开辟一定空间,而生成器只有在访问元素时才会在内存中开辟空间。
a=[1,2,3] #列表
print a
b=(i*2 for i in range(10)) #生成器
print b
>>[1, 2, 3] #内存中的值
>><generator object <genexpr> at 0x025048C8> #内存地址
b=(i*2 for i in range(10))
for i in b: #生成器只有在访问元素时才会在内存中开辟空间
print i
print b
0
2
4
6
8
10
12
14
16
18
<generator object <genexpr> at 0x02154AF8>
注:生成器不能通过像使用列表那样去使用切片、通过索引访问元素值。
只能通过for循环一个个的取值(只有在调用时才会生成相应的数据),生成器只记住当前的位置,当前的值,前面已经输出的值,生成器不会记得,只有一个_next_()方法3.0,2.7next()
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
fib(10) 1
1
2
3
5
8
13
21
34
55
done
def fib(max):
n,a,b = 0,0,1 while n < max:
#print(b)
yield b '''上面的函数和generator仅一步之遥。要把fib函数变成generator, 只需要把print(b)改为yield b ,yidld 也有return的作用'''
a,b = b,a+b
n += 1
return 'done'
f = fib(6)
f
data = fib(10)
print(data)
print(data.__next__())
print(data.__next__())
print("ss")
print(data.__next__())
print(data.__next__())
print(data.__next__())
>><generator object fib at 0x104feaaa0>
>><generator object fib at 0x101be02b0>
>>1
>>1
>>ss
>>2
>>3
>>5
还可通过yield实现在单线程的情况下实现并发运算的效果(准确说是协程)
import time
def consumer(name):
print("%s 准备吃包子啦!" %name)
while True:
baozi = yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
def producer(name):
c = consumer('A')
c2 = consumer('B')
print c
c.next() #这里的c指的是在内存中存放A的内存地址 0x02265490
c2.next()
print("老子开始准备做包子啦!")
for i in range(5):
time.sleep(1)
print("做了2个包子!")
c.send(i)
c2.send(i)
producer("小明") <generator object consumer at 0x021D5490>
A 准备吃包子啦!
B 准备吃包子啦!
老子开始准备做包子啦!
做了2个包子!
包子[0]来了,被[A]吃了!
包子[0]来了,被[B]吃了!
做了2个包子!
包子[1]来了,被[A]吃了!
包子[1]来了,被[B]吃了!
做了2个包子!
包子[2]来了,被[A]吃了!
包子[2]来了,被[B]吃了!
做了2个包子!
包子[3]来了,被[A]吃了!
包子[3]来了,被[B]吃了!
做了2个包子!
包子[4]来了,被[A]吃了!
包子[4]来了,被[B]吃了!
yield 返回当前函数在内存中的地址,
next(),回到yield的执行位置,没有传值的作用。
send(b1) 回到yield的执行位置,可以传值给yield。
迭代器
迭代,顾名思义就是重复做一些事很多次,迭代器是实现了__next__()方法的对象。
能for循环的对象统称为可迭代对象:Iterable,可以使用isinstance()判断一个对象是否是Iterable对象:
from collections import Iteable
isinstance([],Iterable) true
可以被next()调用并不断返回下一个值的对象成为迭代器Iterator,查看对象是否是迭代器使用dir()查看是否用next()函数。
生成器就是一个迭代器,
判断是不是一个迭代器:
from collections import Iterator
isinstance((i for i in range(5)),Iterator)
true
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数:
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
python基础 生成器 迭代器的更多相关文章
- (转)python基础之迭代器协议和生成器(一)
一 递归和迭代 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...
- 第五章:Python基础の生成器、迭代器、序列化和虚拟环境的应用
本课主题 生成器介紹和操作实战 迭代器介紹和操作实战 序例化和反序例化 Json 和 Pickle 操作实战 字符串格式化的应用 创建虚拟环境实战 本周作业 生成器介紹和操作实战 什么是生成器,生成器 ...
- Python基础之迭代器和生成器
阅读目录 楔子 python中的for循环 可迭代协议 迭代器协议 为什么要有for循环 初识生成器 生成器函数 列表推导式和生成器表达式 本章小结 生成器相关的面试题 返回顶部 楔子 假如我现在有一 ...
- python基础之迭代器协议和生成器
迭代器和生成器补充:http://www.cnblogs.com/luchuangao/p/6847081.html 一 递归和迭代 略 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个ne ...
- python基础8 -----迭代器和生成器
迭代器和生成器 一.迭代器 1.迭代器协议指的是对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2. ...
- 【Python基础】迭代器、生成器
迭代器和生成器 迭代器 一 .迭代的概念 #迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单 ...
- python基础之迭代器协议和生成器(一)
一 递归和迭代 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...
- python 基础(五) 迭代器与生成器
迭代器和生成器 迭代器 iterator (1) 迭代对象: 可以直接作用于for循环的 称为可迭代对象(iterable)可以通过 isinstance 判断是否属于可迭代对象 可以直接作用于for ...
- Day4 - Python基础4 迭代器、装饰器、软件开发规范
Python之路,Day4 - Python基础4 (new版) 本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 ...
随机推荐
- Linux 标准IO库介绍
1.标准IO和文件IO有什么区别? (1).看起来使用时都是函数,但是:标准IO是C库函数,而文件IO是Linux系统的API. (2).C语言库函数是由API封装而来的.库函数内部也是通过调用API ...
- 2.docker machine 创建 包含 docker 的 linux 虚拟机
1. 启动 从https://github.com/boot2docker/boot2docker/releases下载iso到~/.docker/machine/cache/里 docker-mac ...
- POJ 3273 Monthly Expense二分查找[最小化最大值问题]
POJ 3273 Monthly Expense二分查找(最大值最小化问题) 题目:Monthly Expense Description Farmer John is an astounding a ...
- linux 下删除乱码的文件夹
[keke.zhaokk@gw2.mpi2.cm10 /home/keke.zhaokk] $ls -i 85082119 dataMining 85082939 ????֦???-???idޢ??? ...
- 使用xb文件恢复mysql数据
1.安装工具Percona XtraBackup MySQL 5.6及之前的版本需要安装 Percona XtraBackup 2.3,安装指导请参见官方文档Percona XtraBackup 2. ...
- 第二代网关GateWay搭建流程
Spring Cloud第二代网关GateWay是由纯Netty开发,底层为Reactor,WebFlux构建,不依赖任何Servlet容器,它不同于Zuul,使用的是异步IO,性能较Zuul提升1. ...
- Ubuntu16.04中Mysql 5.7 安装配置
记录在Ubuntu 16.04安装Mysql 5.7时遇到的一些问题. Mysql安装 使用如下命令进行安装: 1 sudo apt-get install mysql-server mysql-cl ...
- elasticsearch ik中文分词器的使用详解
(基于es5.4)先喵几眼github,按照步骤安装好分词器 link:https://github.com/medcl/elasticsearch-analysis-ik 复习一下常用的操作 .查看 ...
- vue2.0学习之组件间通信
/* child.vue*/ 子组件 <template> <div> /*必须要用div包裹起来,然后在里面写需要的组件内容,这里面和平常写的html是一样的*/ <d ...
- python中的if not
在python中 None, False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()都相当于False ,即: not None == not False = ...