连Python产生器(Generator)的原理都解释不了,还敢说Python用了5年?
mylist = [1, 2, 3]
for i in mylist:
print(i, end = ' ')
mylist = [x*x for x in range(3)]
for i in mylist:
print(i, end=' ')
# 创建产生器
data_generator = (x*x for x in range(3))
print(data_generator)
for i in data_generator:
print(i, end=' ')
print()
print('第二次迭代data_generator,什么都不会输出')
print()
for i in data_generator:
print(i, end=' ')
<generator object <genexpr> at 0x7f95e0154150>
0 1 4
第二次迭代data_generator,什么都不会输出
# 编写产生器函数
def generate_even(max):
for i in range(0, max + 1):
if i % 2 == 0:
yield i
print(generate_even(10))
even_generator = generate_even(10)
for n in even_generator:
print(n, end=' ')
<generator object generate_even at 0x7f814826c450>
0 2 4 6 8 10
even_generator = generate_even(10)
print(even_generator.__next__())
print(even_generator.__next__())
print(even_generator.__next__())
print(even_generator.__next__())
print(even_generator.__next__())
print(even_generator.__next__())
# print(even_generator.__next__()) # 抛出StopIteration异常
总结:产生器本质上就是动态产生待迭代的值,使用完就直接扔掉了,这样非常节省内存空间,但这些值只能被迭代一次。
result = []
result.append(expr)
# 产生不大于max的偶数
def generate_even(max):
for i in range(0, max + 1):
if i % 2 == 0:
yield i even_generator = generate_even(10)
for n in even_generator:
print(n, end=' ') # 将产生器函数改造成普通函数,实际上,就是将yield后面表达式的值都添加在列表中
def generate_even1(max):
evens = []
for i in range(0, max + 1):
if i % 2 == 0:
evens.append(i)
return evens
print()
even_list = generate_even1(10)
for n in even_list:
print(n, end=' ')
在这段代码中有两个函数:generate_even和generate_even1,其中generate_even是产生器函数,generate_even1是普通函数(与generate_even函数的功能完全相同)。按着前面的步骤,将所有产生的偶数都添加到了列表变量evens中,最后返回这个列表变量。这两个函数在使用方式上完全相同。不过从本质上说,generate_even函数是动态生成的偶数,用完了就扔,而generate_even1函数事先将所有产生的偶数都添加到列表中,最后返回。所以从generate_even1函数的改造过程来看,yield的作用就相当于使用append方法将表达式的值添加到列表中,只不过yield并不会保存表达式的值,而append方法会保存表达式的值。
from itertools import * # 这里每一个yield的值必须是可迭代的,才能用chain.from_iterable方法合并
def make_iterables_to_chain():
yield [1,2,3]
yield ['a','b','c']
yield ['hello','world'] for v in make_iterables_to_chain():
print(v)
# 将所有可迭代对象合并成一个可迭代对象
for v in chain.from_iterable(make_iterables_to_chain()):
print('<',v,'>', end = ' ')
print('-------上面的代码相当于下面的写法-------')
a = [1,2,3]
a.extend(['a','b','c'])
a.extend(['hello','world'])
print(a)
for v in a:
print('[',v,']', end = ' ')
# 以可迭代对象形式返回列表的全排列
values = [1,2,3,4]
values_permutations = permutations(values)
for p in values_permutations:
print(p)
[1, 2, 3]
['a', 'b', 'c']
['hello', 'world']
< 1 > < 2 > < 3 > < a > < b > < c > < hello > < world > -------上面的代码相当于下面的写法-------
[1, 2, 3, 'a', 'b', 'c', 'hello', 'world']
[ 1 ] [ 2 ] [ 3 ] [ a ] [ b ] [ c ] [ hello ] [ world ] (1, 2, 3, 4)
(1, 2, 4, 3)
(1, 3, 2, 4)
(1, 3, 4, 2)
(1, 4, 2, 3)
(1, 4, 3, 2)
(2, 1, 3, 4)
(2, 1, 4, 3)
(2, 3, 1, 4)
(2, 3, 4, 1)
(2, 4, 1, 3)
(2, 4, 3, 1)
(3, 1, 2, 4)
(3, 1, 4, 2)
(3, 2, 1, 4)
(3, 2, 4, 1)
(3, 4, 1, 2)
(3, 4, 2, 1)
(4, 1, 2, 3)
(4, 1, 3, 2)
(4, 2, 1, 3)
(4, 2, 3, 1)
(4, 3, 1, 2)
(4, 3, 2, 1)
对本文感兴趣,可以加李宁老师微信公众号(unitymarvel)
关注 「极客起源」 公众号,获得更多免费技术视频和文章。
连Python产生器(Generator)的原理都解释不了,还敢说Python用了5年?的更多相关文章
- python 装饰器、递归原理、模块导入方式
1.装饰器原理 def f1(arg): print '验证' arg() def func(): print ' #.将被调用函数封装到另外一个函数 func = f1(func) #.对原函数重新 ...
- Python装饰器详解
python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...
- http://python.jobbole.com/85056/ 简单 12 步理解 Python 装饰器,https://www.cnblogs.com/deeper/p/7482958.html另一篇文章
好吧,我标题党了.作为 Python 教师,我发现理解装饰器是学生们从接触后就一直纠结的问题.那是因为装饰器确实难以理解!想弄明白装饰器,需要理解一些函数式编程概念,并且要对Python中函数定义和函 ...
- Python装饰器与闭包
闭包是Python装饰器的基础.要理解闭包,先要了解Python中的变量作用域规则. 变量作用域规则 首先,在函数中是能访问全局变量的: >>> a = 'global var' & ...
- Python 装饰器学习
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...
- (转载)Python装饰器学习
转载出处:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方 ...
- Python装饰器学习
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 7 8 # -*- ...
- Python基础(五) python装饰器使用
这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 # -*- coding:gbk -*- '''示例1: 最简单的函数,表示调用了两次 ...
- (二)Python 装饰器
1. 函数 在 Python 中,使用关键字 def 和一个函数名以及一个可选的参数列表来定义函数.函数使用 return 关键字来返回值.定义和使用一个最简单的函数例子: >>> ...
随机推荐
- 【Azure DevOps系列】Azure DevOps构建并发布Nuget程序包
在Azure DevOps中,管道可以用来构建解决方案,O(∩_∩)O哈哈~快万能了,本章主要介绍如何创建Nuget包并且将其发布到Nuget服务器的过程. 前面我创建了一个非常简单的类库,这边我不做 ...
- webpack3.10.0(入门系列基本概念1)
一.概念 webpack的核心是一个用于现代JavaScript应用程序的静态模块打包程序.当webpack处理您的应用程序时,它会递归地构建一个依赖图,其中包含应用程序所需的每个模块,然后将所有这些 ...
- GET请求和POST请求的request和response的中文乱码问题
GET请求(request)中文乱码解决方案: 在Services的server.xml的配置文件的第一个Connector标签中添加属性URIEncoding="UTF-8" P ...
- 手把手带你体验鸿蒙 harmonyOS
wNlRGd.png 前言 本文已经收录到我的 Github 个人博客,欢迎大佬们光临寒舍: 我的 GIthub 博客 学习导图 image.png 一.为什么要尝鲜 harmonyos? wNlfx ...
- VMware安装Centos7并联网使用
一.安装VMware VMwareworkstation官方下载地址: https://www.vmware.com/cn/products/workstation-pro/workstation-p ...
- 初识ABP vNext(9):ABP模块化开发-文件管理
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 创建模块 模块开发 应用服务 运行模块 单元测试 模块使用 最后 前言 在之前的章节中介绍过ABP扩展实体,当时在用户 ...
- nmap端口扫描工具下载和安装使用
1.下载地址 https://nmap.org/download.html 2.下载之后进行安装 选择I Agree 后,建议全选,特别是zenmap,这个是图形化界面,不喜欢命令行格式的可以用zen ...
- oracle之三rman 备份
rman 备份 7.1 归档方式下rman备份常用语法: 7.1.1 backup 备份 1)备份全库:1.1 RMAN> backup database format='/u01/myrman ...
- 血的教训!千万别在生产使用这些 redis 指令
哎,最近小黑哥又双叒叕犯事了. 事情是这样的,前一段时间小黑哥公司生产交易偶发报错,一番排查下来最终原因是因为 Redis 命令执行超时. 可是令人不解的是,生产交易仅仅使用 Redis set 这个 ...
- Github 个人首页的 README,这样玩儿~
本文首发于 Ficow Shen's Blog,原文地址: Github 个人首页的 README,这样玩儿~. 内容概览 前言 创建仓库 修改 README 的内容 总结 前言 大家最近有没有发现这 ...