主要内容:

1、生成器和生成器函数

2、列表推导式

一、生成器

生成器是指就是迭代器,在python中有三种方式来获取生成器:

1、通过生成器函数

2、通过各种推导式来实现生成器

3、通过数据的转换也可以获取生成器

yield 和return的区别:

yield分段来执行一个函数,break停止函数执行。

当程序运行完最后一个yield,那么后面继续进行__next__()程序会报错。

send使用方法:send和__next__()一样可以让生成器执行到下一个yield。

def eat():
print('我吃什么啊')
a = yield '馒头'
print('a = ',a)
b = yield '大饼'
print('b = ',b)
c = yield '韭菜盒子'
print('c = ',c)
yield 'GAME OVER'
gen = eat() #获取生成器
ret1 = gen.__next__()
print(ret1) #结果:我吃什么啊 馒头
ret2 = gen.send('胡辣汤')
print(ret2) #结果:a = 胡辣汤 大饼
ret3 = gen.send('狗粮')
print(ret3) #结果:b = 狗粮 韭菜盒子
ret4 = gen.send('猫粮')
print(ret4) #结果:c = 猫粮 GAME OVER

send 和 __next__()区别:

1、send和 __next__()都是让生成器向下走一次

2、send可以给上一个yield的位置传递值,不能给最后一个yield发送值。在第一次执行生成器的时候不能使用send()。

生成器可以使用for循环来获取内部元素:

def func():
print(111)
yield 222
print(333)
yield 444
print(555)
yield 666
gen = func()
for i in gen:
print(i)
# 结果:
#
#
#
#
#
#
for i in list(gen):
print(i)
# 结果:
#
#
#
#
#
#

二、列表推导式,生成器表达式及其他推导式

首先我们先看一下这样的代码, 给出一个列表, 通过循环, 向列表中添加1-14 :

lst = []
for i in range(1, 15):
lst.append(i)
print(lst)

替换成列表推导式:

lst = [i for i in range(1, 15)]
print(lst)

列表推导式的常用写法:

[ 结果 for 变量 in 可迭代对象 if 条件 ]

生成器表达式和列表推导式的语法基本上是一样的. 只是把[ ]替换成()

# 获取1-100内能被3整除的数
gen = (i for i in range(1,100) if i % 3 == 0)
for num in gen:
print(num)
# 100以内能被3整除的数的平方
gen = (i * i for i in range(100) if i % 3 == 0)
for num in gen:
print(num)
# 寻找名字中带有两个e的人的名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven',
'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
# 不⽤推导式和表达式
result = []
for first in names:
for name in first:
if name.count("e") >= 2:
result.append(name)
print(result)
# 推导式
gen = (name for first in names for name in first if name.count("e") >= 2)
for name in gen:
print(name)

生成器表达式和列表推导式的区别:
           1. 列表推导式比较耗内存. 一次性加载. 生成器表达式几乎不占用内存. 使用的时候才分配和使用内存。
           2. 得到的值不一样. 列表推导式得到的是一个列表. 生成器表达式获取的是一个生成器。
       举个栗子:
           同样一篮子鸡蛋. 列表推导式: 直接拿到一篮子鸡蛋. 生成器表达式: 拿到一个老母鸡. 需要鸡蛋就给你下鸡蛋。

def func():
print(111)
yield 222
print(333)
yield 444
print(555)
g = func() #生成器g
g1 = (i for i in g) #生成器g1,但是g1的数据来源于g
g2 = (i for i in g1) #生成器g2,来源g1
print(list(g)) #获取g中的数据,这时func()才会被执行,结果为:111 333 555 [222,444]
print(list(g1))#获取g1中的数据,g1的数据来源于g,但是g已经取完了,g1也就没有数据,结果为[]
print(list(g2))#和g1同理,结果为[]

深坑----生成器,要值得时候才拿值。

字典推导式:

# 把字典中的key和value互换
dic = {'a': 1, 'b': ''}
new_dic = {dic[key]: key for key in dic}
print(new_dic)
# 在以下list中. 从lst1中获取的数据和lst2中相对应的位置的数据组成⼀个新字典
lst1 = ['jay', 'jj', 'sylar']
lst2 = ['周杰伦', '林俊杰', '邱彦涛']
dic = {lst1[i]: lst2[i] for i in range(len(lst1))}
print(dic)

集合推导式:

lst = [1, -1, 8, -8, 12]
# 绝对值去重
s = {abs(i) for i in lst}
print(s)

总结: 推导式有, 列表推导式, 字典推导式, 集合推导式, 没有元组推导式
         生成器表达式: (结果 for 变量 in 可迭代对象 if 条件筛选)
         生成器表达式可以直接获取到生成器对象. 生成器对象可以直接进行for循环. 生成器具有惰性机制。

def add(a,b):
return a+b
def test():
for r_i in range(4):
yield r_i
g = test()
for n in [2,10]:
g = (add(n,i) for i in g)
print(list(g)) # 结果:[20, 21, 22, 23]

2018.8.13 python中生成器和生成器表达式的更多相关文章

  1. python中的迭代器 生成器 装饰器

    什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,_ ...

  2. python中函数和生成器的运行原理

    #!/usr/bin/env python # -*- coding:utf-8 -*- # author:love_cat # python的函数是如何工作的 # 比方说我们定义了两个函数 def ...

  3. python中迭代器和生成器

    l=[1,2,3,4] for n in l: print n 在看上面这段代码的时候,我们没有显式的控制列表的偏移量,就可以自动的遍历了整个列表对象.那么for 语句是怎么来遍历列表l的呢?要回答这 ...

  4. Python中的列表生成器,迭代器的理解

    首先,思考一个问题,比如,我们想生成0-100的列表,我们怎么做? 当然,可以写成 list1=[1,2,3...,100] 可以看出,这种方法不适合生成长的列表,那么Python中就可以利用已有的列 ...

  5. Python中的yield生成器的简单介绍

    Python yield 使用浅析(整理自:廖 雪峰, 软件工程师, HP 2012 年 11 月 22 日 ) 初学 Python 的开发者经常会发现很多 Python 函数中用到了 yield 关 ...

  6. 为什么for循环可以遍历list:Python中迭代器与生成器

    1 引言 只要你学了Python语言,就不会不知道for循环,也肯定用for循环来遍历一个列表(list),那为什么for循环可以遍历list,而不能遍历int类型对象呢?怎么让一个自定义的对象可遍历 ...

  7. 2018.8.15 python 中的sorted()、filter()、map()函数

    主要内容: 1.lambda匿名函数 2.sorted() 3.filter() 4.map() 5.递归函数 一. lambda匿名函数 为了解决一些简单的需求而设计的一句话函数 # 计算n的n次方 ...

  8. 2018.8.14 python中的内置函数(68个)

    主要内容: python中68个内置函数的功能及使用方法

  9. 2018.8.9 python中的动态传参与命名空间

    主要内容: 1.函数参数 ----动态传参 2.名称空间与作用域 3.函数的嵌套 4.global,nonlocal关键字 一.函数参数 ------动态传参 形参的第三种:动态传参 动态传参分为两种 ...

随机推荐

  1. 死磕 java同步系列之mysql分布式锁

    问题 (1)什么是分布式锁? (2)为什么需要分布式锁? (3)mysql如何实现分布式锁? (4)mysql分布式锁的优点和缺点? 简介 随着并发量的不断增加,单机的服务迟早要向多节点或者微服务进化 ...

  2. druid 连接池的配置参数

    介绍 DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0.DBCP.PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生 ...

  3. Spark 学习笔记之 Spark history Server 搭建

    在hdfs上建立文件夹/directory hadoop fs -mkdir /directory 进入conf目录  spark-env.sh 增加以下配置 export SPARK_HISTORY ...

  4. Vue躬行记(2)——指令

    Vue不仅内置了各类指令,包括条件渲染.事件处理等,还能注册自定义指令. 一.条件渲染 条件渲染的指令包括v-if.v-else.v-else-if和v-show. 1)v-if 该指令的功能和条件语 ...

  5. idea tomcat提示Unable to ping server at localhost:1099

    idea启动tomcat报错Unable to ping server at localhost:1099 是 IDEA配置的jdk版本 与 tomcat的jdk版本不配导致的

  6. http post 请求,带参数,带请求头

    #!/usr/bin/env python # -*- coding: utf-8 -*- import requests import json url = 'http://............ ...

  7. 低效sql语句执行缓慢引起的大量占用服务器的CPU问题处理 (优化心得)

    1> 2> 3> 4> 5>删除不良的执行计划后执行时间仍然有150s,这实在是太慢了,继续查看原sql代码,发现父表的关联条件放在了子查询里,这是应该避免的 调整原sq ...

  8. 记录一次jvm内存泄露的问题

    前些天,运维告诉我刚上线的java服务占用CPU过高. 以下是发现解决问题的具体流程. 1:通过#top命令查看,我的java服务确实把CPU几乎占满了,如图 可看到18400这个进程CPU占用达到了 ...

  9. 2. spring 应用之IOC

    本文是作者原创,版权归作者所有.若要转载,请注明出处 我们知道Spring Framework 最重要的功能就是IoC (Inversion of Control ),也叫DI(dependency ...

  10. java普通项目打包成可执行jar文件时如何添加第三包

    在java的web项目中,引用第三方包的时候非常简单.因为在web项目上中,默认有一个web-inf文件夹.web-inf文件夹下有一个lib文件夹,如果有用到第三方包,直接丢进去就行了.但是对于普通 ...