Python3.5迭代器与生成器用法实例分析


Posted in Python onApril 30, 2019

本文实例讲述了Python3.5迭代器与生成器用法。分享给大家供大家参考,具体如下:

1、列表生成式

通过列表生成式可以直接创建一个列表。代码:a = [i*2 for i in range(10)]

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu
#列表生成式
a = [i*2 for i in range(10)]
print(a)

运行结果:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

由于受内存限制,列表容量肯定是有限的。创建一个包含100万个元素的列表,不仅占用很大的存储空间,若只访问前面的几个元素,后边的绝大多数元素占用空间浪费。

如果列表元素可以按照某种算法推算出来,那是否可以在循环过程中不断推算后续的元素?这样就不必创建完整的列表list,从而节省大量的空间。

2、生成器

在Python中,一边循环一边计算的机制,叫做:生成器(generator)。创建一个生成器的方法有很多:

(1)将一个列表生成式的[]改成(),就创建一个生成器。代码:b = (i*2 for i in range(10))

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu
#列表生成式
a = [i*2 for i in range(10)]
print(a)
print("type of a:",type(a))
#生成器
b = (i*2 for i in range(10))
print(b)
print("type of b:",type(b))
for i in b:
  print(i)

运行结果:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
type of a: <class 'list'>
<generator object <genexpr> at 0x008B8D20>
type of b: <class 'generator'>
0
2
4
6
8
10
12
14
16
18

结论:生成器的元素只有在调用的时候才生成相应的,调用到哪一次才会生成到哪一次的元素,只记住当前的位置。

注意:列表可以直接打印出每一个元素,而生成器不能用切片的形式去取,会出错误。

打印出生成器generator的每一个元素的方法:如果要一个一个打印出来,要通过next()函数获得生成器generator的下一个返回值

生成器generator保存的是算法,每次调用print(next(b)),就计算出生成器b的下一个元素的值,直到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

#生成器
b = (i*2 for i in range(10))
print(next(b))
print(next(b))
print(next(b))
print(next(b))

运行结果:

0
2
4
6

不断调用next(b)很麻烦,可以利用for循环,因为生成器generator也是可迭代的对象

(2)当推算的算法比较复杂时,用类似列表生成式的for循环无法实现,还可以用函数来实现生成器

例如:著名的斐波那契数列(Fibonaccl),除了第一个和第二个数之外,任意一个数都由前两个数相加得到:1, 1, 2, 3, 5, 8, 13, 21, 34, ...

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu
def fibonaccl(max):
  n,a,b = 0,0,1
  while n < max:
    print(b)
    a,b = b,a + b
    n = n + 1
  return 'done'
fibonaccl(10)

运行结果:

1
1
2
3
5
8
13
21
34
55

Python3.5迭代器与生成器用法实例分析

总结:Fibonaccl函数实际上定义了斐波那契数列的推算规则,可以从第一个元素开始,推算出后续任意元素,这种逻辑非常类似generator。

Fibonaccl函数和生成器generator只有一步之遥,要把Fibonaccl函数变成生成器generator,只需要将print(b)修改为yield b就可以了。

最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。

而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

即:yield保存了函数的中断状态,返回当前状态的值,函数停在这里,后边还可以继续回来。

另外,函数可以不再等待其执行结束,可以中断在某个地方做其他的事情,结束之后还可以继续回来接着往下执行(具有并行的效果)。

def fibonaccl(max):
  n,a,b = 0,0,1
  while n < max:
    yield b
    a,b = b,a + b
    n = n + 1
  return 'done'
print(fibonaccl(15))
f = fibonaccl(15)
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print("===========")
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print("=========start loop========")  #接着打印后边的元素
for i in f:
  print(i)

运行结果:

<generator object fibonaccl at 0x00548D50>
1
1
2
3
===========
5
8
13
21
=========start loop========
34
55
89
144
233
377
610

用for循环调用generator时,发现拿不到generator的return语句的返回值。

如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中。

def fibonaccl(max):
  n,a,b = 0,0,1
  while n < max:
    yield b
    a,b = b,a + b
    n = n + 1
  return 'done'
g = fibonaccl(6)
while True:
   try:
     x = next(g)
     print('g:', x)
   except StopIteration as e:
     print('Generator return value:', e.value)
     break

运行结果:

g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

3、生成器并行的实现——单线程下的并行效果

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu
#生成器并行的实现——生产者、消费者模型
import time
def consumer(name):
  print("%s 准备吃包子啦!" %name)
  while True:
    baozi = yield     #yield保存当前状态返回
    print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
def producer(name):
  c = consumer('A')
  c2 = consumer('B')
  c.__next__()     #next只唤醒yield
  c2.__next__()
  print("开始准备做包子啦!")
  for i in range(3):
    time.sleep(1)
    print("做了2个包子!")
    c.send(i)     #send唤醒yield同时给它传值
    c2.send(i)
producer("alex")

运行结果:

A 准备吃包子啦!
B 准备吃包子啦!
开始准备做包子啦!
做了2个包子!
包子[0]来了,被[A]吃了!
包子[0]来了,被[B]吃了!
做了2个包子!
包子[1]来了,被[A]吃了!
包子[1]来了,被[B]吃了!
做了2个包子!
包子[2]来了,被[A]吃了!
包子[2]来了,被[B]吃了!

更多关于Python相关内容可查看本站专题:《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
给Python IDLE加上自动补全和历史功能
Nov 30 Python
在Python的Django框架中创建和使用模版
Jul 15 Python
python僵尸进程产生的原因
Jul 21 Python
Python排序搜索基本算法之堆排序实例详解
Dec 08 Python
Python+matplotlib+numpy绘制精美的条形统计图
Jan 02 Python
python调用tcpdump抓包过滤的方法
Jul 18 Python
Python爬虫的两套解析方法和四种爬虫实现过程
Jul 20 Python
python 获取页面表格数据存放到csv中的方法
Dec 26 Python
python如何从文件读取数据及解析
Sep 19 Python
Python爬虫 urllib2的使用方法详解
Sep 23 Python
python plt可视化——打印特殊符号和制作图例代码
Apr 17 Python
微软开源最强Python自动化神器Playwright(不用写一行代码)
Jan 05 Python
python使用Paramiko模块实现远程文件拷贝
Apr 30 #Python
Django学习笔记之为Model添加Action
Apr 30 #Python
Python Opencv实现图像轮廓识别功能
Mar 23 #Python
python opencv实现图像边缘检测
Apr 29 #Python
Python Django给admin添加Action的方法实例详解
Apr 29 #Python
python实现微信机器人: 登录微信、消息接收、自动回复功能
Apr 29 #Python
Python opencv实现人眼/人脸识别以及实时打码处理
Apr 29 #Python
You might like
咖啡界又出新概念,无需咖啡豆的分子咖啡
2021/03/03 咖啡文化
实时抓取YAHOO股票报价的代码
2006/10/09 PHP
慎用preg_replace危险的/e修饰符(一句话后门常用)
2013/06/19 PHP
THINKPHP支持YAML配置文件的设置方法
2015/03/17 PHP
常见的5个PHP编码小陋习以及优化实例讲解
2021/02/27 PHP
jquery的$getjson调用并获取远程的JSON字符串问题
2012/12/10 Javascript
jquery struts 验证唯一标识(公用方法)
2013/03/27 Javascript
Ext4.2的Ext.grid.plugin.RowExpander无法触发事件解决办法
2014/08/15 Javascript
Nodejs Post请求报socket hang up错误的解决办法
2014/09/25 NodeJs
javascript仿百度输入框提示自动下拉补全
2016/01/07 Javascript
javascript实现随机显示星星特效
2016/01/28 Javascript
jquery.cookie.js实现用户登录保存密码功能的方法
2016/04/15 Javascript
JS简单实现tab切换效果的多窗口显示功能
2016/09/07 Javascript
使用DeviceOne实现微信小程序功能
2016/12/29 Javascript
基于JavaScript实现的希尔排序算法分析
2017/04/14 Javascript
Webpack实战加载SVG的方法
2017/12/26 Javascript
解决在vue项目中,发版之后,背景图片报错,路径不对的问题
2018/03/06 Javascript
Vue-cli@3.0 插件系统简析
2018/09/05 Javascript
vue+php实现的微博留言功能示例
2019/03/16 Javascript
微信小程序学习笔记之获取位置信息操作图文详解
2019/03/29 Javascript
初学vue出现空格警告的原因及其解决方案
2019/10/31 Javascript
JavaScript进阶(一)变量声明提升实例分析
2020/05/09 Javascript
Taro小程序自定义顶部导航栏功能的实现
2020/12/17 Javascript
Python中scatter函数参数及用法详解
2017/11/08 Python
快速解决pyqt5窗体关闭后子线程不同时退出的问题
2019/06/19 Python
详解Python并发编程之从性能角度来初探并发编程
2019/08/23 Python
Python切割图片成九宫格的示例代码
2020/03/10 Python
OpenCV灰度化之后图片为绿色的解决
2020/12/01 Python
项目经理的岗位职责
2013/11/23 职场文书
职业生涯规划书的格式
2013/12/29 职场文书
财务专业大学生职业生涯规划范文
2013/12/30 职场文书
医药专业应届毕业生求职信范文
2014/01/01 职场文书
婚礼证婚人演讲稿
2014/09/13 职场文书
python用海龟绘图写贪吃蛇游戏
2021/06/18 Python
MySQL系列之二 多实例配置
2021/07/02 MySQL
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang