python笔记十(列表生成式、字典生成式、生成器、生成器的并行)
一、列表生成式
列表生成式就是python设置的可以用来可以生成列表的。
如要生成一个0-9的列表我们可以通过以下代码实现:
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
但是如果生成的列表较为复杂呢?例如生成包含0²、1²、2²。。。9²这样一个列表;
>>> L = []
>>> for i in range(10):
... L.append(i*i)
...
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
在上述代码中,我们通过for循环将数值append到列表L中,虽然可以实现,但是也是low爆了~~~,以下通过一行代码搞定!!!
>>> [i*i for i in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
除此之外,列表生成式还可以生成更为复杂的列表。通过列表生成式可以快速生成格式化的列表、字典
>>> d ={"name":"nadech","age":"","address":"NANJING"}
>>> [key+"="+value for key,value in d.items()]
['name=nadech', 'age=22', 'address=NANJING']
>>> from numpy.random import randn
>>> data ={i:randn() for i in range(7)}
>>> data
{0: 0.05824826050892203, 1: 0.08046687699730207, 2: 1.860740808203487, 3: 1.577136929714018, 4: -0.5473223742129686, 5: 0.13849329354272613, 6: 1.4133333866268165}
二、生成器
通过列表生成式,我们可以直接创建一个列表的所有元素。
但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
如果列表可以按照需求,一边循环一边计算,就可以解决上述问题。这种机制就叫做生成器(generator)。
生成器共有两种形式,第一种就是把列表生成式中的[ ]改为( );第二种就是含有yield
>>> g = (i*i for i in range(1,3))
>>> next(g)
1
>>> next(g)
4
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> (i*i for i in range(10))
<generator object <genexpr> at 0x0000029EA41490F8>
>>> for i in g:
... print(i)
...
1
4
上述代码加粗部分可以看出,创建生成器返回的是一个生成器对象的地址,并不是直接包含所有的元素的列表。
通过调用next,可以生成下个元素的值,不过在实际使用中我们并不会通过多次调用next,而是通过for循环来获取生成器的元素。
第二种我们要介绍的就是包含yield的,首先我们先实现打印输出这样一串数字,除了第一个数,后一个数都等于前两个数字的和 1,1,2,3,5,8....这就是著名的斐波那契数列,不要被这名字吓到,总之就是实现输出上边的一串数字。
>>> 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(5)
1
1
2
3
5
'done'
接下来,我们对上述代码进行一处修改,把print改为yield
>>> def fib(max):
... n,a,b = 0,0,1
... while n<max:
... yield(b)
... a,b = b,a+b
... n=n+1
... return "done"
...
>>> fib(5)
<generator object fib at 0x000001F8B9C2AF68>
>>> o = fib(6)
>>> for i in o:
... print (i)
...
1
1
2
3
5
8
可见,命令窗口返回一个generator对象的内存地址。通过迭代输出生成器 o中的数字。
但是,细心的朋友可能发现,我们通过for循环来输出生成器的内容的时候,并没有输出return的“done”,这样我们就需要通过next来依次输出,同时就伴随另外一个问题的产生,当next输出到最后的时候,会抛出一个StopIteration的异常,我们需要将次异常捕获。(异常的捕获后边会详细介绍)
>>> while True:
... try:
... x = next(o)
... print("o:",x)
... except StopIteration as e:
... print("RETURN VALUE:", e.value)
... break
...
o: 1
o: 1
o: 2
o: 3
o: 5
o: 8
RETURN VALUE: done
三、生成器的并行
搞清楚了生成器的特点,那么我们简单的利用生成器来实现一个并行的效果,实际上这是一个假的并行。
这个生成器并行的例子,叫做大猪和小猪吃包子。
import time
def consumer(name):
print("%s 准备好吃包子了" % name)
while True:
type = yield #此处的yield,可以接受producer中send的传值
print("%s包子被%s 吃了" % (type, name)) def producer(name):
print("%s 已经准备好做包子了~~~~"%name)
c = consumer("大猪") #这时候不是正常的函数调用了,只是生成一个生成器队形,不执行函数体内容,调用next会执行
c1 = consumer("小猪") next(c)
next(c1) items = ["白菜","菠菜","生菜"]
for item in items :
time.sleep(1)
print("%s已经做好了两个包子"%name)
c.send(item)
c1.send(item) producer("nadech")
以上代码中,我们先定义了消费者函数,这个函数就用来描述大猪和小猪吃包子,我们可以看到该函数包含有yield,实际上它是一个生成器。与上个例子中的斐波那契函数不同的是这里的yield,可以接受该生成器send过来的一个值。
python笔记十(列表生成式、字典生成式、生成器、生成器的并行)的更多相关文章
- Python 列表生成式 & 字典生成式
Python 列表生成式 & 字典生成式 通过生成式可以更加简洁地生成列表和字典 列表生成式 对比 直接生成数据后加入列表示例: user_list = list() for i in ran ...
- Python 函数递归-三元表达式-列表生成式-字典生成式-匿名函数-内置函数
上节课复习: 1. 无参装饰器 def 装饰器名字(func): def wrapper(*args,**kwargs): res = func(*args,**kwargs) return res ...
- python字符串、列表和字典的说明
python字符串.列表和字典的说明 字符串.列表.字典 字符串的作用存储一段数据信息.例如 info = '我爱北京天安门' ,在调取的时候可以直接调取,灵活方便,print(info) 就可以把刚 ...
- python递归-三元表达式-列表生成式-字典生成式-匿名函数-部分内置函数-04
递归 递归: # 函数在调用阶段直接或间接地又调用了自身 应用场景: # 将列表中的数字依次打印出来(循环的层数是你必须要考虑的点) --> l = [1, [2, [3, [4, [5, ...
- Python 1.2 列表和字典基础
一. List创建.索引.遍历和内置增删函数 1.列表是Python的内置可变对象,由Array实现,支持任意类型的添加.组合和嵌套. L = [] # list declare L = [1, 1. ...
- [转载]Python 元组、列表、字典、文件
python的元组.列表.字典数据类型是很python(there python is a adjective)的数据结构.这些结构都是经过足够优化后的,所以如果使用好的话,在某些area会有很大的益 ...
- python学习之列表和字典
列表 基本操作>>>len([1,3,4])3 >>>[1,2,3]+[4,5,6] +号两边必须是相同类型[1,2,3,4,5,6] >>> ...
- python 1:列表和字典
初学Python, 对列表和字典的嵌套使用. phoneBook = [] #列表 list peopleInfo = {} #字典 dict i=0 while i<3: peopleInfo ...
- Python笔记(十四)_永久存储pickle
pickle模块:将所有的Python对象转换成二进制文件存放 应用场景:编程时最好将大对象(列表.字典.集合等)用pickle写成永久数据包供程序调用,而不是直接写入程序 写入过程:将list转换为 ...
随机推荐
- DOM节点删除之empty和remove区别
要移除页面上节点是开发者常见的操作,jQuery提供了几种不同的方法用来处理这个问题,这里我们开仔细了解下empty和remove方法 empty 顾名思义,清空方法,但是与删除又有点不一样,因为它只 ...
- web框架之Flask
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...
- POJ-3292 Semi-prime H-numbers---筛素数
题目链接: https://vjudge.net/problem/POJ-3292 题目大意: 定义一种数叫H-numbers,它是所有能除以四余一的数. 在H-numbers中分三种数: 1.H-p ...
- Why deep learning?
1. 深度学习中网络越深越好么? 理论上说是这样的,因为网络越深,参数也越多,拟合能力也越强(但实际情况是,网络很深的时候,不容易训练,使得表现能力可能并不好). 2. 那么,不同什么深度的网络,在参 ...
- html5的八大特性
HTML5是用于取代1999年所制定的 HTML 4.01 和 XHTML 1.0 标准的 HTML [1](标准通用标记语言下的一个应用)标准版本:现在仍处于发展阶段,但大部分浏览器已经支持某些 H ...
- java 连接mysql
目前还沉浸在java自动化测试中不能自拔! 自动化过程中免不了要从数据库取值与期望值比较,目前我项目刚开始就需要用到了. 下面我把操作过程写下来: 我的项目框架是java+maven+testNG,所 ...
- APP开发外包时常见的错误
时代在发展,科技在进步,很多企业都想要开发出属于自己的一款APP.然而,不是每个企业都有开发团队或是专门雇一个技术人员来做的,有一个好方法就是把开发APP的工作外包出去,找一个比较好的外包公司根据自己 ...
- 基于线程池的多线程售票demo2.0(原创)
继上回基于线程池的多线程售票demo,具体链接: http://www.cnblogs.com/xifenglou/p/8807323.html以上算是单机版的实现,特别使用了redis 实现分布式锁 ...
- SpringMVC 自定义类型转换器
先准备一个JavaBean(Employee) 一个Handler(SpringMVCTest) 一个converters(EmployeeConverter) 要实现的输入一个字符串转换成一个emp ...
- vue中自定义组件(插件)
vue中自定义组件(插件) 原创 2017年01月04日 22:46:43 标签: 插件 在vue项目中,可以自定义组件像vue-resource一样使用Vue.use()方法来使用,具体实现方法: ...