连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 关键字来返回值.定义和使用一个最简单的函数例子: >>> ...
随机推荐
- php反序列化总结与学习
基础知识: 1.php类与对象 2.魔术函数 3.序列化方法 类与对象 <?php class test{ public $var = "hello world"; publ ...
- 01 fs模块
1 fs.readFile 异步执行函数 /** fs 读取文件相对路径是相对终端命令行所在的路径 process.cwd()返回终端命令行的绝对路径 * */ fs = require('fs') ...
- ASP.NET Uploadify 上传文件过大 报错(http error)借鉴,以防忘记
Uploadify上传文件原来很早之前用过,没发现什么问题.今天再使用过程中,当文件大于30M的时候就会报错404.查看错误消息提示配置最大上传太小了.需要修改. 记得原来配置上传文件大小在这里:&l ...
- 一键部署k8s
本人学习安装kubernetes时,顺便整理了安装脚本,可以通过执行一个脚本,自动二进制安装好1台master+2台node的k8环境.方便需要学习k8s的同学. 百度网盘:https://pan.b ...
- Activiti7 绑定业务主键以及流程定义 流程实例的挂起和激活
绑定业务主键businessKey /** * 绑定业务主键 */ @Test public void bindingBusinessKey() { // 获取RuntimeService Runti ...
- 正则表达式在Java中应用的三种典型场合:验证,查找和替换
正则式在编程中常用,总结在此以备考: package regularexp; import java.util.regex.Matcher; import java.util.regex.Patter ...
- 执行Python程序出现“SyntaxError: Non-UTF-8 code starting with '\xb6'...”错误怎么办?
如果文件中有中文,直接执行python xx.py会出现以下错误: SyntaxError: Non-UTF- code starting with '\xb6' in file XX.py on l ...
- 20190917-01VI/VIM编辑器 000 002
VI是Unix 操作系统和类Unix操作系统中最通用的文本编辑器. VIM编辑器是从VI发展出来的一个性能更强大的文本编辑器.可以主动的以字体颜色便被语法的正确性,方便程序设计.VIM与VI编辑器完全 ...
- 获取JSO字符串的key和value值
import com.alibaba.fastjson.JSON; import java.util.ArrayList; import java.util.HashMap; import java. ...
- 在腾讯云云函数计算上部署.NET Core 3.1
云厂商(腾讯云.Azure等)提供了Serverless服务,借助于Serverless,开发人员可以更加专注于代码的开发,减少运维的成本.腾讯云的函数计算提供了很多运行库,对.NET的支持需要通过c ...