当前位置: 首页 > news >正文

python可迭代对象相关的内建函数_第八章 Python可迭代对象、迭代器和生成器

8.1 可迭代对象(Iterable)

大部分对象都是可迭代,只要实现了__iter__方法的对象就是可迭代的。

__iter__方法会返回迭代器(iterator)本身,例如:>>> lst = [1,2,3]

>>> lst.__iter__()

Python提供一些语句和关键字用于访问可迭代对象的元素,比如for循环、列表解析、逻辑操作符等。

判断一个对象是否是可迭代对象:>>> from collections import Iterable  # 只导入Iterable方法

>>> isinstance('abc', Iterable)

True

>>> isinstance(1, Iterable)

False

>>> isinstance([], Iterable)

True

这里的isinstance()函数用于判断对象类型,后面会讲到。

可迭代对象一般都用for循环遍历元素,也就是能用for循环的对象都可称为可迭代对象。

例如,遍历列表:>>> lst = [1, 2, 3]

>>> for i in lst:

...   print i

...

1

2

3

8.2 迭代器(Iterator)

具有next方法的对象都是迭代器。在调用next方法时,迭代器会返回它的下一个值。如果next方法被调用,但迭代器没有值可以返回,就会引发一个StopIteration异常。

使用迭代器的好处:

1)如果使用列表,计算值时会一次获取所有值,那么就会占用更多的内存。而迭代器则是一个接一个计算。

2)使代码更通用、更简单。

8.2.1 迭代器规则

回忆下在Python数据类型章节讲解到字典迭代器方法,来举例说明下迭代器规则:>>> d = {'a':1, 'b':2, 'c':3}

>>> d.iteritems()

# 判断是否是迭代器

>>> from collections import Iterator

>>> isinstance(d, Iterator)

False

>>> isinstance(d.iteritems(), Iterator)

True

# 使用next方法。

>>> iter_items = d.iteritems()

>>> iter_items.next()

('a', 1)

>>> iter_items.next()

('c', 3)

>>> iter_items.next()

('b', 2)

由于字典是无序的,所以显示的是无序的,实际是按照顺序获取的下一个元素。

8.2.2 iter()函数

使用iter()函数转换成迭代器:

语法:

iter(collection) -> iterator

iter(callable, sentinel) -> iterator>>> lst = [1, 2, 3]

>>> isinstance(lst, Iterator)

False

>>> lst.next()  # 不是迭代器是不具备next()属性的

Traceback (most recent call last):

File "", line 1, in 

AttributeError: 'list' object has no attribute 'next'

>>> iter_lst = iter(lst)

>>> isinstance(iter_lst, Iterator)

True

>>> iter_lst.next()

1

>>> iter_lst.next()

2

>>> iter_lst.next()

3

8.2.3 itertools模块

itertools模块是Python内建模块,提供可操作迭代对象的函数。可以生成迭代器,也可以生成无限的序列迭代器。

有下面几种生成无限序列的方法:

count([n]) --> n, n+1, n+2, ...

cycle(p) --> p0, p1, ... plast, p0, p1, ...

repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times

也有几个操作迭代器的方法:

islice(seq, [start,] stop [, step]) --> elements from

chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...

groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)

imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...

ifilter(pred, seq) --> elements of seq where pred(elem) is True

1)count生成序列迭代器>>> from itertools import *  # 导入所有方法

# 用法 count(start=0, step=1) --> count object

>>> counter = count()

>>> counter.next()

0

>>> counter.next()

1

>>> counter.next()

2

......

可以使用start参数设置开始值,step设置步长。

2)cycle用可迭代对象生成迭代器# 用法 cycle(iterable) --> cycle object

>>> i = cycle(['a', 'b', 'c'])

>>> i.next()

'a'

>>> i.next()

'b'

>>> i.next()

'c'

3)repeat用对象生成迭代器# 用法 repeat(object [,times]) -> create an iterator which returns the object,就是任意对象

>>> i = repeat(1)

>>> i.next()

1

>>> i.next()

1

>>> i.next()

1

......

可使用无限次。

也可以指定次数:>>> i = repeat(1, 2)

>>> i.next()

1

>>> i.next()

1

>>> i.next()

Traceback (most recent call last):

File "", line 1, in 

StopIteration

4)islice用可迭代对象并设置结束位置# 用法 islice(iterable, [start,] stop [, step]) --> islice object

>>> i = islice([1,2,3],2)

>>> i.next()

1

>>> i.next()

2

>>> i.next()

Traceback (most recent call last):

File "", line 1, in 

StopIteration

正常的话也可以获取的3。

5)chain用多个可迭代对象生成迭代器# 用法 chain(*iterables) --> chain object

>>> i = chain('a','b','c')

>>> i.next()

'a'

>>> i.next()

'b'

>>> i.next()

'c'

6)groupby将可迭代对象中重复的元素挑出来放到一个迭代器中# 用法 groupby(iterable[, keyfunc]) -> create an iterator which returns

>>> for key,group in groupby('abcddCca'):

...   print key,list(group)

...

a ['a']

b ['b']

c ['c']

d ['d', 'd']

C ['C']

c ['c']

a ['a']

groupby方法是区分大小写的,如果想把大小写的都放到一个迭代器中,可以定义函数处理下:>>> for key,group in groupby('abcddCca', lambda c: c.upper()):

...   print key, list(group)

...

A ['a']

B ['b']

C ['c']

D ['d', 'd']

C ['C', 'c']

A ['a']

7)imap用函数处理多个可迭代对象# 用法 imap(func, *iterables) --> imap object

>>> a = imap(lambda x, y: x * y,[1,2,3],[4,5,6])

>>> a.next()

4

>>> a.next()

10

>>> a.next()

18

8)ifilter过滤序列# 用法 ifilter(function or None, sequence) --> ifilter object

>>> i = ifilter(lambda x: x%2==0,[1,2,3,4,5])

>>> for i in i:

...   print i

...

2

4

当使用for语句遍历迭代器时,步骤大致这样的,先调用迭代器对象的__iter__方法获取迭代器对象,再调用对象的__next__()方法获取下一个元素。最后引发StopIteration异常结束循环。

博客地址:http://lizhenliang.blog.51cto.com

QQ群:323779636(Shell/Python运维开发群)

8.3 生成器(Generator)

什么是生成器?

1)任何包含yield语句的函数都称为生成器。

2)生成器都是一个迭代器,但迭代器不一定是生成器。

8.3.1 生成器函数

在函数定义中使用yield语句就创建了一个生成器函数,而不是普通的函数。

当调用生成器函数时,每次执行到yield语句,生成器的状态将被冻结起来,并将结果返回__next__调用者。冻结意思是局部的状态都会被保存起来,包括局部变量绑定、指令指针。确保下一次调用时能从上一次的状态继续。

以生成斐波那契数列举例说明yield使用:

斐波那契(Fibonacci)数列是一个简单的递归数列,任意一个数都可以由前两个数相加得到。#!/usr/bin/python

# -*- coding: utf-8 -*-

def fab(max):

n, a, b = 0, 0, 1

while n 

print b

a, b = b, a + b

n += 1

fab(5)

# python test.py

1

1

2

3

5

使用yied语句,只需要把print b改成yield b即可:#!/usr/bin/python

# -*- coding: utf-8 -*-

def fab(max):

n, a, b = 0, 0, 1

while n 

yield b

# print b

a, b = b, a + b

n += 1

print fab(5)

# python test.py

可见,调用fab函数不会执行fab函数,而是直接返回了一个生成器对象,上面说过生成器就是一个迭代器。那么就可以通过next方法来返回它下一个值。>>> import test

>>> f = test.fab(5)

>>> f.next()

1

>>> f.next()

1

>>> f.next()

2

>>> f.next()

3

>>> f.next()

5

每次fab函数的next方法,就会执行fab函数,执行到yield b时,fab函数返回一个值,下一次执行next方法时,代码从yield b的吓一跳语句继续执行,直到再遇到yield。

8.3.2 生成器表达式

在第四章 Python运算符和流程控制章节讲过,简化for和if语句,使用小括号()返回一个生成器,中括号[]生成一个列表。

回顾下:# 生成器表达式

>>> result = (x for x in range(5))

>>> result

 at 0x030A4FD0>

>>> type(result)

# 列表解析表达式

>>> result = [ x for x in range(5)]

>>> type(result)

>>> result

[0, 1, 2, 3, 4]

第一个就是生成器表达式,返回的是一个生成器,就可以使用next方法,来获取下一个元素:>>> result.next()

0

>>> result.next()

1

>>> result.next()

2

......

相关文章:

  • mysql workbench连接jsp_JSP连接sql server2000数据库
  • 爱可生 mysql监控_数据库Prometheus 数据采集3-爱可生
  • java分割_Java中分割字符串的两种方法实例详解
  • java https 证书_JavaHTTPS客户端证书认证
  • java byte to hex_java 转换byte位hex字符串的工具代码
  • java泛型设计_使用java泛型设计通用方法
  • java线程 数据队列_java多线程从队列中取出数据执行
  • java 给url增加参数_Java给指定URL字符串添加值和获取URL字符串中的参数值
  • java copy object_Java Object 对象拷贝
  • java 几种样式_JAVA几种常见的编码格式
  • mysql5.7解压版停止_MySQL5.7.13解压版安装及常见问题
  • ios java 加密_iOS与Java的RSA加密解密
  • java 动态页面_Java中的动态网页:如何在Java中创建网页?
  • cacti命令行进入mysql_Cacti监控mysql数据库服务器实现过程
  • java webpoi 导出excel 2007_Java POI导入导出Excel文件-excel2007兼容包
  • CentOS7简单部署NFS
  • crontab执行失败的多种原因
  • DataBase in Android
  • dva中组件的懒加载
  • hadoop集群管理系统搭建规划说明
  • js中forEach回调同异步问题
  • MobX
  • mysql 数据库四种事务隔离级别
  • Netty源码解析1-Buffer
  • Node 版本管理
  • select2 取值 遍历 设置默认值
  • use Google search engine
  • VUE es6技巧写法(持续更新中~~~)
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 从0实现一个tiny react(三)生命周期
  • ------- 计算机网络基础
  • 近期前端发展计划
  • 浅谈web中前端模板引擎的使用
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 项目实战-Api的解决方案
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​批处理文件中的errorlevel用法
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (1)虚拟机的安装与使用,linux系统安装
  • (3)(3.5) 遥测无线电区域条例
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转) 深度模型优化性能 调参
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • ***详解账号泄露:全球约1亿用户已泄露
  • **PHP分步表单提交思路(分页表单提交)
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料