python作为一个既面向对象,又支持函数式编程的语言,函数的使用方面有很多特点。

比如:闭包,装饰器,迭代器等

函数的高级应用

容器:生活中常见的容器有哪些?袋子,盆子,水杯,书包,铅笔盒。。。

容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个的迭代获取,可以用in,not in等关键字判断某个元素是否包含在容器中。在python中常见的容器对象有:

list, tuple, dict, str, set

容器你可以把它看做一个房子,一个柜子,一个盒子,里面可以塞任何东西,从技术角度来说,当他可以用来询问某个元素是否包含在其中时,那么这个对象就可以看做一个容器。

1 in [1, 2, 3]   # True
4 not in [1, 2, 3, 4] # False
4 in {1, 2, 3} # False
4 not in {1, 2, 3, 4} # False

一、迭代器

回想一下,到目前为止,能用for循环进行遍历的数据类型主要有哪些呢?dict,tuple,str,set,list

1.1 可迭代对象

可迭代对象和容器一样是一种通俗的叫法,并不是指某种具体的数据类型,list是可迭代对象,dict是可迭代对象,set也是可迭代对象。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

前面说的序列和集合类型也是基于这个原理

那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:

from collections import Iterable

# str是否可迭代
print(isinstance("abc", Iterable)) # True
# list是否可迭代
print(isinstance([1,2,3], Iterable)) # True
# 整数是否可迭代
print(isinstance(123, Iterable)) # False

1.2 迭代器

现在已经有很多对象可以使用for循环,而且相对于其他语言,pythonfor循环的使用方式非常优雅,简洁和便利

for`循环的背后就是迭代器

迭代器使用遍及python,并且使用方式统一

但凡是返回一个迭代器的对象,都可以成为可迭代对象。比如range对象。


1.3 迭代器的工作原理

使用迭代器的步骤简述如下:

  1. 调用内置函数iter(container), 把容器作为参数传递进去,返回一个对象,这个对象就是一个迭代器对象。容器对象就是咱们前边说的str,list
  2. 迭代器对象中有一个方法__next()__,这个方法每调用一次,就可以访问到容器中的一个元素,我们自己要调用的话,只需要调用内置函数next(it)就可以了
  3. 当容器中最后一个元素被迭代后, 再调用__next()__方法, 则会抛出一个StopIteration异常, for循环捕捉到这个异常后就可以终止循环了.

当运行代码:

list1 = [1, 2, 3]
for x in list1:
....

实际执行的情况是

1.3 使用迭代器访问字符串中的元素

s = "acdefgh"

# 获取字符串 s 的迭代器, 其实等价于 it = s.__iter__()
it = iter(s) print(next(it))# 迭代第一个元素
print(next(it))
print(next(it))
print(next(it))
print(next(it))

1.4 使用迭代器访问列表中的元素

s = [10, 30, 40, 20, 2]
it = iter(s)
print(next(it)) # 10
print(next(it)) # 30
print(next(it)) # 40

二、生成器

生成器算的上是python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。他只需要一个yield关键字。生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。

generator(生成器)是一个简单且强大的创建迭代器的工具

生成器除了使用yield之外, 就像一个正常的函数, 想在任何地方返回数据, 只需要添加yield就可以了.

我们调用next()函数, 一旦碰到yield则返回yield后的数据, python 并且可以保存当前的状态和位置, 下次再调用next(), 则继续从此处执行.

# 生成能够迭代整数 1-n 的迭代器函数.  调用这个方法, 方法内的代码并不会立即执行, 而是返回一个生成器对象
def foo(n):
for i in range(1, n):
yield i # 每次碰到 yield, 则在此暂停, 并保存这个位置 for i in foo(20):
print(i)

当然也可以使用下面的方式去使用生成器函数

def foo(n):
for i in range(1, n):
yield i # 每次碰到 yield, 则在此暂停, 并保存这个位置 it = foo(20) print(next(it))
print(next(it))

1.2.1 生成器表达式

生成器表达式(Generator Expressions), 是一个对象, 他执行的结果和以前学习的列表推导类似, 但会迭代的生成结果.

他的语法也与列表类似, 只是需要把以前的[]换成()

语法:

it = (express for item in iterator)
def foo(n):
for i in range(1, n + 1):
yield i # foo(20)返回的迭代器生成一个新的迭代器
it = (x * x for x in foo(20)) for y in it:
print(y)

1.2.2 生成器表达式和列表的差异

从写法上来看,生成器表达式使用(), 而列表用[]. 但是他们之间还是有很重要的差异.

他们的主要区别在于其中的元素(数据)的生成时间不同!

  1. 列表创建成功之后, 那么他里面的元素也已经创建成功, 而且是实实在在的占据着内存! 也就是说, 从物理上来看他们已经存在了.
  2. 而生成器表达式不一样, 仅仅是创建了一个生成器而已, 那些元素还没有创建. 只有当你使用for或者next()的时候才会根据需要来创建元素.
  3. 所以, 生成器不可能有添加, 删除等这些方法.
  4. 如果数据量比较大的时候, 使用生成器表达式的性能要好于列表.
  5. 列表推倒只能生成列表, 而生成器表达式可以根据需要生成任何类型的序列.

Python第六章-函数05-迭代器&生成器的更多相关文章

  1. Python第六章-函数06-高阶函数

    函数的高级应用 二.高阶函数 高级函数, 英文叫 Higher-order Function. 那么什么是高阶函数呢? 在说明什么是=高阶函数之前, 我们需要对函数再做进一步的理解! 2.1 函数的本 ...

  2. Python第六章-函数01-函数的概念和使用

    函数 为了便于程序的维护和更好的实现模块化,好的程序都会分解为很多函数. 可以这么说,对于任何的编程语言,函数都是一个非常重要的概念. python 不仅简化了函数的定义过程,而且还大量借鉴了其他函数 ...

  3. Python第六章-函数02-函数的作用域

    函数 三.作用域规则 有了函数之后,我们必须要面对一个作用域的问题. 比如:你现在访问一个变量,那么 python 解析器是怎么查找到这个变量,并读取到这个变量的值的呢? 依靠的就是作用域规则! 3. ...

  4. Python第六章-函数04-递归函数和拉姆达表达式

    五.递归函数 什么叫递归(recusive)? 你拿两个镜子互相面对着, 然后去看镜子, 会发现每个镜子中很多个镜子, 层层的嵌套, 无穷尽, 这就是一种递归! 从前有坐山, 山里有座庙, 庙里有个老 ...

  5. 简学Python第六章__class面向对象编程与异常处理

    Python第六章__class面向对象编程与异常处理 欢迎加入Linux_Python学习群  群号:478616847 目录: 面向对象的程序设计 类和对象 封装 继承与派生 多态与多态性 特性p ...

  6. python第六章:三大利器(装饰器,迭代器,生成器)--小白博客

    python装饰器 什么是装饰器?在不修改源代码和调用方式的基础上给其增加新的功能,多个装饰器可以装饰在同一个函数上 # 原理(个人理解):将原函数(bar)的内存地址重新赋值,进行覆盖.新值为装饰器 ...

  7. Python函数系列-迭代器,生成器

    一 迭代器 一 迭代的概念 #迭代器即迭代的工具,那什么是迭代呢?#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而不 ...

  8. 《Python 学习手册4th》 第十六章 函数基础

    ''' 时间: 9月5日 - 9月30日 要求: 1. 书本内容总结归纳,整理在博客园笔记上传 2. 完成所有课后习题 注:“#” 后加的是备注内容 (每天看42页内容,可以保证月底看完此书) “重点 ...

  9. 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】

    Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...

随机推荐

  1. 什么是x86什么是x64 它们有什么区别

    1.内存寻址不同: 32位系统,最大支持3.5G内存,如果在32位系统中使用4G或更大的内存,电脑最多只可以识别3.4G左右可用,而64位系统最大可以支持128G大内存. 2.运算速度不同: 64位系 ...

  2. 超详细的HDFS读写流程详解(最容易理解的方式)

    HDFS采用的是master/slaves这种主从的结构模型管理数据,这种结构模型主要由四个部分组成,分别是Client(客户端).Namenode(名称节点).Datanode(数据节点)和Seco ...

  3. Xml反序列化记录

    1.概述 公司项目遇到一个需要对接webservice的,webservice大部分用的都是xml来传输的,这里记录一下xml反序列化遇到的问题 2.xml工具类 xml序列化: public sta ...

  4. 汇编语言-[bx]和loop指令和多个段

    5.1 [BX]和内存单元的描述 要完成描述一个内存单元,需要两种信息: 内存单元的地址: 可以用 [0] 表示一个内存单元, 0 表示单元的偏移地址,段地址默认在 ds 中: 同样也可以用 [bx] ...

  5. 有关js的date的相关知识

    最近做项目,用了new Date().getTime()获取本地时间,但是如果用户篡改了手机时间,程序漏洞明显暴露.所以如果为保证程序的稳健安全性,应该是要使用网络时间的,也就是服务器时间.原理就是使 ...

  6. 使用python3编写程序,生成10个随机数,每个元素的值介于1到100之间,并计算所有元素的和、平均值。

    代码如下: import random n = 0 sum = 0 while n < 10: num = random.randint(1, 100) sum = sum + num n += ...

  7. 织梦cms文章内容页上下篇单独获得URL和文章名称修改

    1.打开/include/arc.archives.class.php ,查找   $this->PreNext['pre']    //约813行 在其下一行插入: $this->Pre ...

  8. python opencv Sobel、Laplace、canny算子的边缘提取 以及参数解析

    前提:各种算子不完全区分好坏,但根据我实际操作分析得到,有的算子之间效果大相径庭,但有的也很相似,也就是各有各的用法,这里按 Sobel.Laplace.canny三种算子作比较,看其结果: 一.  ...

  9. What is the difference between shades and shadows?

    Shade is the darkness of an object not in direct light, while shadows are the silhouette of an objec ...

  10. Xamarine ContentPage.ToolbarItems 未显示/不显示在界面

    将页面封装到NavigationPage中.在App.xaml.cs的构造函数中 将 MainPage = new MainPage(); 替换为 MainPage = new NavigationP ...