列表生成式:

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对象,但listdictstr虽然是Iterable,却不是Iterator

listdictstrIterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

  

  

 

 

 

python基础 生成器 迭代器的更多相关文章

  1. (转)python基础之迭代器协议和生成器(一)

    一 递归和迭代 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...

  2. 第五章:Python基础の生成器、迭代器、序列化和虚拟环境的应用

    本课主题 生成器介紹和操作实战 迭代器介紹和操作实战 序例化和反序例化 Json 和 Pickle 操作实战 字符串格式化的应用 创建虚拟环境实战 本周作业 生成器介紹和操作实战 什么是生成器,生成器 ...

  3. Python基础之迭代器和生成器

    阅读目录 楔子 python中的for循环 可迭代协议 迭代器协议 为什么要有for循环 初识生成器 生成器函数 列表推导式和生成器表达式 本章小结 生成器相关的面试题 返回顶部 楔子 假如我现在有一 ...

  4. python基础之迭代器协议和生成器

    迭代器和生成器补充:http://www.cnblogs.com/luchuangao/p/6847081.html 一 递归和迭代 略 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个ne ...

  5. python基础8 -----迭代器和生成器

    迭代器和生成器 一.迭代器 1.迭代器协议指的是对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2. ...

  6. 【Python基础】迭代器、生成器

    迭代器和生成器 迭代器 一 .迭代的概念 #迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单 ...

  7. python基础之迭代器协议和生成器(一)

    一 递归和迭代 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...

  8. python 基础(五) 迭代器与生成器

    迭代器和生成器 迭代器 iterator (1) 迭代对象: 可以直接作用于for循环的 称为可迭代对象(iterable)可以通过 isinstance 判断是否属于可迭代对象 可以直接作用于for ...

  9. Day4 - Python基础4 迭代器、装饰器、软件开发规范

    Python之路,Day4 - Python基础4 (new版)   本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 ...

随机推荐

  1. Linux-进程状态和system函数

    1.进程的5种状态 (1).就绪态. 这个进程当前所有运行条件就绪,只要得到CPU时间就能直接运行. (2).运行态 就绪态时得到了CPU就进入运行态开始运行. (3).僵尸态 进程已经结束但是父进程 ...

  2. 第一行代码近期bug及解决

    Android学习笔记(5)----启动 Theme.Dialog 主题的Activity时程序崩溃的解决办法https://www.cnblogs.com/dongling/p/6476308.ht ...

  3. GCC与G++区别

    gcc和g++的区别总结:gcc: GNU C Compilerg++: GNU C++ Compiler 共同点:均属于the GNU Compiler Collection,gcc是鼻祖,后来才有 ...

  4. Python访问Amazon官网异常

    使用Python访问亚马逊(Amazon)官网,如果没有将headers更改为浏览器的信息, 有几率会触发:检测到当前可能是自动程序,需要输入验证码: 将header修改成浏览器后,需要等一段时间或者 ...

  5. Python语言学习:字符串常用的方法

    python字符串常用的方法 1. find( ):在字符串中搜索指定的值并返回它被找到的位置,如果没有找到,则返回-1 string.find(value,start,end) #value:必需, ...

  6. 4412开发板QtE系统下MT6620-wifi的测试

    基于iTOP4412系统烧写并启动之后,使用如下命令.wpa_passphrase XXX "YYY " >> /etc/wpa_supplicant.conf其中 X ...

  7. 十八、linux系统分区

    一.磁盘存储结构图:这里注意下,分区标有64字节,则每个分区有16字节,MBR引导分区有446字节,共有510字节,一个扇区有512字节,还有俩个字节是分区结束标识.比如隐藏文件等标识,都是这2个字节 ...

  8. c/c++[001]:start

    作为一个学校课程跳过c语言的萌新,这次重新学习c/c++从源头上明白这两种不同的输入输出还是很有必要 scanf()是C语言中的一个输入函数.与printf函数一样,都被声明在头文件stdio.h里, ...

  9. ionic 创建服务命令

    创建Util工具库 ionic g provider Util

  10. SwaggerConfig

    package me.zhengjie.common.swagger2; import com.google.common.base.Predicates; import org.springfram ...