生成器

生成器的本质就是迭代器,那么还为什么有生成器呢,两者唯一的不同就是迭代器都是Python给你提供能够的已经写好的工具或者通过数据转化得来的。而生成器是需要我们自己用Python代码构建的工具。

生成器的构建方式:

在python中有两种方式来创建生成器:

  • 通过生成器函数

  • 通过生成器推导式

生成器函数:

首先我们来一个简单的函数结构:

def func():
print('111')
return 222
result = func()
print(result)

没得问题,那么在看看生成器函数是啥样的。

def func():
print('111')
yield 222
result = func()
print(result)
# <generator object func at 0x000002980E331C10>

以这样打印,就给打印了个这东西。这意思是,当函数看到返回值是yield的时候,就说明这个函数时一个生成器函数。返回的是一个生成器。那么要调用怎么办呢。

def func():
print('111')
yield 222
result = func() #这会还不会调用,而是获取到一个生成器
ret = result.__next__() #这个时候函数才会被执行。
print(ret) #而且yield会将func返回的222给ret

就是将return该成yield,再用next来提取就成了。

还有yield可以写多个,一个next对应一个yield,next多了就会报错。

def func():
print('111')
yield 222
print('222')
yield 333
print('333')
yield 444
result = func()
print(next(result))
print(next(result))
print(next(result))

发现它的用处了吗~?? 那就是可以暂停函数执行,并返回出来。这样带来的好处是可以暂时执行其他的,然后再返回执行下面的代码。

当一个数字循环不用保存而只是使用一次的话,那么使用yield是非常省内存的方法。

def func():
for i in range(10000):
yield '包子'+ str(i)
v = func()
for i in range(200):
print(v.__next__())

send方法:

def func():
for i in range(10000): #3-10-17
count = yield str(i)+'来了' #4-8-11-15-18
print(f'{count}再吃包子{i}') #9-16
v = func() #1
print(v.__next__()) #2-5
for i in range(2): #6-13
v2 = v.send(i) #7-14-19
print(v2) #12-20

这里比较绕哦,需要好好看。

send和next的相同点,不同点:

相同点:

  • 都可以让商城器对应的yield向下执行一次

  • 都可以获取到yield生成的值

不同点:

  • 第一次获取yield值智能用next,不能用send(可以用send(None))

  • send可以给上一个yield传递值

yield from:

def func():
lis =[1,2,3,4,5]
yield lis
v = func()
print(next(v))
'''
[1,2,3,4,5]
'''


def func():
lis =[1,2,3,4,5]
yield from lis
v = func()
print(next(v))
print(next(v))
print(next(v))
print(next(v))
'''
1
2
3
4
5
'''

yield from的主要作用是将列表中的每一个元素返回一次。next多了还是会报错。没啥鸟用。了解即可。

生成器表达式:

gen = (i**2 for i in range(10))
for i2 in gen:
print(i2) gen = (i for i in range(10) if i > 2) for i2 in gen: print(i2)

推导式

主要目的是为了方便将比较单一且有规律的做法使用简单的语句进行处理。

缺点是比较占用内存资源。

基本语句:

lis = [ i for i in range(10)]
print(lis)

这样就生成了一个0-9的列表。

推导式的分类:

  1. 循环推导式

    #[变量(值) for 变量 in iterable]

  2. 筛选推导式

    #[变量 for 变量 in iterable if 条件]

列表推导式:

lis = [ i for i in range(10)]     #基本格式
lis = [ i if i > 3 else 8 for i in range(10)] #循环range,得出的结果依次判断,如果成立将添加,如果不成立就改成8
lis = [i for i in range(10) if i > 3] #循环range,得出的结果依次判断,如果为True,那么就添加,如果为False,就不添加
lis = [lambda x:x*i for i in range(10)] #得到的是循环10次的lambda表达式,如果lis[0](2),那么意思是巡行第1个lambda函数,将2传入到你,将得到18结果。
def num():
return [lambda x:i * x for i in range(4)]
print([m(2) for m in num()])

字典推导式:

lis1 = ['a','b','c']
lis2 = ['1','2','3']
dic = {lis1[i]:lis2[i] for i in range(len(lis1))}
print(dic)

lis1 = 'abc'
lis2 = '123'
dic = {lis1[i]:lis2[i] for i in range(len(lis1))}
print(dic)

集合推导式:

lis = [1,2,3,4,5,2,2,1,1,3,2,1]
s = {i for i in lis}
print(s)

Python——生成器&推导式的更多相关文章

  1. Python生成器/推导式/生成器表达式

    一   生成器 生成器的本质就是迭代器 生成器的特点和迭代器一样,取值方式和迭代器一样(__next__(),  send():  给上一个yield传值) 生成器一般由生成器函数或者生成器表达式来创 ...

  2. python 生成器推导式与列表推导式的区别

    生成器表达式现用现生成,列表推导式一次性生成静态数据 L = [2, 3, 5, 7] L2 = (x**2+1 for x in L) it = iter(L2) print(next(it)) L ...

  3. 12.Python略有小成(生成器,推导式,内置函数,闭包)

    Python(生成器,推导式,内置函数,闭包) 一.生成器初始 生成器的本质就是迭代器,python社区中认为生成器与迭代器是一种 生成器与迭代器的唯一区别,生成器是我们自己用python代码构建成的 ...

  4. Python进阶(四)----生成器、列表推导式、生成器推导式、匿名函数和内置函数

    Python进阶(四)----生成器.列表推导式.生成器推导式.匿名函数和内置函数 一丶生成器 本质: ​ 就是迭代器 生成器产生的方式: ​ 1.生成器函数

  5. 记录我的 python 学习历程-Day12 生成器/推导式/内置函数Ⅰ

    一.生成器 初识生成器 生成器的本质就是迭代器,在python社区中,大多数时候都把迭代器和生成器是做同一个概念. 唯一的不同就是: 迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来 ...

  6. Python函数04/生成器/推导式/内置函数

    Python函数04/生成器/推导式/内置函数 目录 Python函数04/生成器/推导式/内置函数 内容大纲 1.生成器 2.推导式 3.内置函数(一) 4.今日总结 5.今日练习 内容大纲 1.生 ...

  7. Python之路-迭代器 生成器 推导式

    迭代器 可迭代对象 遵守可迭代协议的就是可迭代对象,例如:字符串,list dic tuple set都是可迭代对象 或者说,能被for循环的都是可迭代对象 或者说,具有对象.__iter__方法的都 ...

  8. python 列表推导式,生成器推导式,集合推导式,字典推导式简介

    1.列表推导式multiples = [i for i in range(30) if i % 2 is 0]names = [[],[]]multiples = [name for lst in n ...

  9. python的推导式 —— 列表推导式、集合和字典推导式

    python的推导式是用于快速处理数据的方法. 主要有:列表推导式.集合推导式和字典推导式 import time import numpy as np 列表推导式: 1. 速度快 t1 = time ...

随机推荐

  1. redis创建集群至少需要几个节点?至少需要几个master节点?

    描述: 这也算个思考吧,通过redis-trib.rb可创建redis集群,然后通过--replicas后面接的数字,表示1个主节点对应几个从节点,那么我就做了如下的测试,想要达到的效果就是有6个节点 ...

  2. java Random 带权重的随机选择

    实际场景中,经常要从多个选项中随机选择一个,不过,不同选项经常有不同的权重. /** * Created by xc on 2019/11/23 * 带权重的随机选择 */ public class ...

  3. LeetCode_476. Number Complement

    476. Number Complement Easy Given a positive integer, output its complement number. The complement s ...

  4. mysqldump导出完整sql脚本

    #导出某个数据库--结构+数据 shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt db_name |gzip -9 > /db ...

  5. 设计模式php+java版本(1) 基础篇 七大原则

    2019年9月6日11:15:46 关于设计模式,其实就是编程思想的一个体现,有比较完善的编程思想写出的项目代码和没有编程思想的写出的差距巨大,代码的可读性,可维护性,可扩展性天差地别,有些刚接触的编 ...

  6. IDEA中类文件显示J,IDEA Unable to import maven project: See logs for details

    今天用了下lemon清理了下垃圾后,IDEA打开项目类文件图标由C变为J,在IDEA右侧的Maven Project中点击刷新提示IDEA Unable to import maven project ...

  7. Java8学习之异步编程

    异步编程 所谓异步其实就是实现一个无需等待被调用函数的返回值而让操作继续运行的方法 创建任务并执行任务 无参创建 CompletableFuture<String> noArgsFutur ...

  8. spring boot 实现定时任务

    定时任务或者说定时调度,是系统中比较普遍的一个功能,例如数据归档.清理,数据定时同步(非实时),定时收发等等都需要用到定时任务,常见的定时调度框架有Quartz.TBSchedule等. 如何在Spr ...

  9. Python中的sync和wait函数的使用

    转自这篇博文,备忘: https://blog.csdn.net/Likianta/article/details/90123678 https://www.cnblogs.com/xinghun85 ...

  10. delphi xe6 JSON 测试

    System.JSON   ISuperJSOn   mORMETJSON   QJSON  测试 我在测试时发现系统自带的JSON  占用内存大一但多了就会出现内存泄漏的问题 我用的Flst< ...