zoukankan      html  css  js  c++  java
  • 80%人都没搞懂python迭代器和生成器的区别,本文详解

     

    今天,我们来为大家介绍一下Python的进阶知识——迭代器和生成器,你们知道是怎么运行工作的吗?

    迭代

    1. 什么是迭代?

    使用for循环遍历取值的过程叫做迭代,比如:使用for循环遍历列表获取值的过程

    p1.jpg

    2. 可迭代对象

    使用for循环遍历取值的对象叫做可迭代对象, 比如:列表、元组、字典、集合、range、字符串

    3.如何判断一个对象是否可以迭代
    另外注意:光理论是不够的。这里顺便免费送大家一套2020最新python入门到高级项目实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,还可以跟老司机交流讨教!

    可以使用isinstance()判断一个对象是否是可迭代对象

    p1.jpg

    Python 迭代器

    上面简单的介绍了一下迭代,迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。现在正式进入主题:迭代器,迭代器是一个可以记住遍历的位置的对象。

    迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。

    迭代器只能往前不会后退。

    迭代器有两个基本的方法:iter() 和 next(),且字符串,列表或元组对象都可用于创建迭代器,迭代器对象可以使用常规 for 语句进行遍历,也可以使用 next() 函数来遍历。

    具体的实例:

    p1.jpg

    iter()函数与next()函数

    list、tuple等都是可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。iter()函数实际上就是调用了可迭代对象的 __iter__ 方法。

    p1.jpg

    注意,当我们已经迭代完最后一个数据之后,再次调用next()函数会抛出StopIteration的异常,来告诉我们所有数据都已迭代完成,不能再执行next()函数了。

    lsit 生成式(列表生成式)

    1、创建 list 的方式

    之前经过我们的学习,都知道如何创建一个 list ,可是有些情况,用赋值的形式创建一个 list 太麻烦了,特别是有规律的 list ,一个一个的写,一个一个赋值,太麻烦了。比如要生成一个有 30 个元素的 list ,里面的元素为 1 - 30 。我们可以这样写:

    p1.jpg

    输出的结果:

    p1.jpg

    这个其实在之前也有提到过:比如有个例子,打印九九乘法表,用这个方法其实就几句代码就可以了,可以参考之前文章:循环语句的运用

    但是,如果用到 list 生成式,可以一句代码就生成九九乘法表了。具体看代码:

    p1.jpg

    最后输出的结果:

    p1.jpg

    不过,这里我们先要了解如何创建 list 生成式

    2、list 生成式的创建

    首先,lsit 生成式的语法为:

    p1.jpg

    第一种语法:首先迭代 iterable 里所有内容,每一次迭代,都把 iterable 里相应内容放到iter_var 中,再在表达式中应用该 iter_var 的内容,最后用表达式的计算值生成一个列表。

    第二种语法:加入了判断语句,只有满足条件的内容才把 iterable 里相应内容放到 iter_var 中,再在表达式中应用该 iter_var 的内容,最后用表达式的计算值生成一个列表。

    其实不难理解的,因为是 list 生成式,因此肯定是用 [] 括起来的,然后里面的语句是把要生成的元素放在前面,后面加 for 循环语句或者 for 循环语句和判断语句。

    例子:

    p1.jpg

    输出的结果:

    p1.jpg

    可以看到,就是把要生成的元素 x * x 放到前面,后面跟 for 循环,就可以把 list 创建出来。那么 for 循环后面有 if 的形式呢?又该如何理解:

    p1.jpg

    输出的结果:

    p1.jpg

    这个例子是为了求 1 到 10 中偶数的平方根,上面也说到, x * x 是要生成的元素,后面那部分其实就是在 for 循环中嵌套了一个 if 判断语句。

    那么有了这个知识点,我们也可以猜想出,for 循环里面也嵌套 for 循环。具体示例:

    p1.jpg

    输出的结果:

    p1.jpg

    其实知道了 list 生成式是怎样组合的,就不难理解这个东西了。因为 list 生成式只是把之前学习的知识点进行了组合,换成了一种更简洁的写法而已。

    生成器

    利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。为了达到记录当前状态,并配合next()函数进行迭代使用,我们可以采用更简便的语法,即生成器(generator)。生成器是一类特殊的迭代器。

    创建生成器的方法1

    要创建一个生成器,有很多种方法。第一种⽅法很简单,只要把一个列表生成式的 [ ] 改成 ( )

    p1.jpg

    创建 L 和 G 的区别仅在于最外层的 [ ] 和 ( ) , L 是一个列表,而 G 是一个生成器。我们可以直接打印出列表L的每一个元素,而对于生成器G,我们可以按照迭代器的使用方法来使用,即可以通过next()函数、for循环、list()等方法使用。

    p1.jpg

    创建生成器的方法2

    generator⾮常强大。如果推算的算法比较复杂,用类似列表生成式的 for 循环无法实现的时候,还可以用函数来实现。 我们用著名的斐波那契数列来举例,回想我们在上一次⽤迭代器的实现方式:

    p1.jpg

    注意,在用迭代器实现的方式中,我们要借助几个变量(n、current、num1、num2)来保存迭代的状态。现在我们用生成器来实现一下。

    p1.jpg

    迭代器和生成器综合例子

    因为迭代器和生成器基本是互通的,因此有些知识点需要综合在一起

    1、反向迭代

    反向迭代,也是常有的需求了,比如从一开始迭代的例子里,有个输出 list 的元素,从 1 到 5 的

    p1.jpg

    那么我们从 5 到 1 呢?这也很简单, Python 中有内置的函数 reversed()

    p1.jpg

    方向迭代很简单,可是要注意一点就是:反向迭代仅仅当对象的大小可预先确定或者对象实现了 __reversed__() 的特殊方法时才能生效。 如果两者都不符合,那你必须先将对象转换为一个列表才行

    其实很多时候我们可以通过在自定义类上实现 __reversed__() 方法来实现反向迭代。不过有些知识点在之前的篇节中还没有提到,不过可以相应的看下,有编程基础的,学完上面的知识点应该也能理解的。

    p1.jpg

    输出的结果是 1 到 30 然后 30 到 1 ,分别是顺序打印和倒序打印

    2、同时迭代多个序列

    你想同时迭代多个序列,每次分别从一个序列中取一个元素。你遇到过这样的需求吗?

    为了同时迭代多个序列,使用 zip() 函数,具体示例:

    p1.jpg

    输出的结果:

    p1.jpg

    其实 zip(a, b) 会生成一个可返回元组 (x, y) 的迭代器,其中 x 来自 a,y 来自 b。 一旦其中某个序列到底结尾,迭代宣告结束。 因此迭代长度跟参数中最短序列长度一致。注意理解这句话喔,也就是说如果 a , b 的长度不一致的话,以最短的为标准,遍历完后就结束。

    利用 zip() 函数,我们还可把一个 key 列表和一个 value 列表生成一个 dict (字典),如下:

    p1.jpg

    输出的结果:

    p1.jpg

    这里提一下, zip() 是可以接受多于两个的序列的参数,不仅仅是两个。
    最后注意:光理论是不够的。这里顺便免费送大家一套2020最新python入门到高级项目实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,还可以跟老司机交流讨教!

    本文的文字及图片来源于网络加上自己的想法,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

  • 相关阅读:
    MSSQL大量数据时,建立索引或添加字段后保存更改超时该这么办
    POJ 3261 Milk Patterns (后缀数组)
    POJ 1743 Musical Theme (后缀数组)
    HDU 1496 Equations (HASH)
    694. Distinct Substrings (后缀数组)
    POJ 1222 EXTENDED LIGHTS OUT (枚举 或者 高斯消元)
    POJ 1681· Painter's Problem (位压缩 或 高斯消元)
    POJ 1054 The Troublesome Frog (hash散列)
    HDU 1716 排列2
    HDU 4405 Aeroplane chess (概率DP & 期望)
  • 原文地址:https://www.cnblogs.com/chengxuyuanaa/p/13065794.html
Copyright © 2011-2022 走看看