连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 关键字来返回值.定义和使用一个最简单的函数例子: >>> ...
随机推荐
- 「查缺补漏」巩固你的Nginx知识体系
Nginx篇 基本介绍 Nginx是一款轻量级的 Web服务器 / 反向代理服务器 / 电子邮件(IMAP/POP3)代理服务器,主要的优点是: 支持高并发连接,尤其是静态界面,官方测试Nginx能够 ...
- JavaScript函数及面向对象
函数及面向对象 目录 函数及面向对象 1. 定义函数 1. 定义方式一 2. 定义方式二 2. 调用函数 1. 参数问题 2. arguments 3. rest 3. 变量的作用域 1 . var的 ...
- Oracle Rman备份恢复和管理
参考资料: Oracle之Rman入门指南 一步一步学Rman Rman简介 Rman-Recover manager恢复管理工具. Oracle集成了很多环境的一个数据库备份和恢复的工具. Rman ...
- 掌控安全sql注入靶场pass-05
1.判断注入点 1 and 1=1 1 and 1=2 考虑存在布尔盲注 布尔盲注解释 当不能像前面那样直接在网页中显示我们要的数据时就需要用到盲注,来得到数据库之类的名字.基于布尔的盲注就是通过判断 ...
- C指针那点事儿
指针: 用来存放变量地址的变量,就成为"指针变量". 定义: 一般形式:类名标识符 *指针变量名; int *p; float *q; "*"是说明符,用来说明 ...
- [程序员代码面试指南]递归和动态规划-换钱的方法数(DP,完全背包)
题目描述 给定arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim,求组成aim的方法数. 解题思路 完全背包 和"求换钱的 ...
- java安全编码指南之:字符串和编码
目录 简介 使用变长编码的不完全字符来创建字符串 char不能表示所有的Unicode 注意Locale的使用 文件读写中的编码格式 不要将非字符数据编码为字符串 简介 字符串是我们日常编码过程中使用 ...
- Bootstrap学习第一天
听说bootstrap很火,页面做的非常好看,今天我决定开始学习bootstrap. bootstrap是一种响应式前端技术,可以用于构建适应多种设备的网站页面,当页面尺寸变化时会根据变化的尺寸适应设 ...
- Linux实战(13):Centos8 同步时间
前言 以下操作是通过ntpdate命令实现同步 timedatectl set-timezone Asia/Shanghai # 设置时区 rpm -ivh http://mirrors.wlnmp. ...
- 小白的springboot之路(十八)、i18n多语言支持(后端篇)
0-前言 在有些系统中,比如网站,往往需要支持多国语言,英文版中文版什么的,这个其实也不难: 今天我们就来介绍spring boot中用i18n在后端支持多语言: 当然,也可以直接在前端用i18n直接 ...