今天就给大家介绍一下Python的进阶知识——迭代器和生成器。你知道它们是如何工作的吗?
迭代
1. 什么是迭代?
使用for循环遍历值的过程称为迭代,例如:使用for循环遍历列表获取值的过程
2. 可迭代对象
使用for循环遍历取值的对象叫做可迭代对象, 比如:
列表、元组、字典、集合、range、字符串
3.如何判断一个对象是否可以迭代
可以使用isinstance()判断一个对象是否是可迭代对象
Python 迭代器
以上简单介绍了迭代,它是Python最强大的功能之一,也是一种访问集合元素的方式。现在正式进入正题:迭代器,迭代器是一种可以记住遍历位置的对象。
迭代器对象从集合的第一个元素开始访问,直到访问完所有元素。
迭代器只能往前不会后退。
迭代器有两个基本方法:iter() 和 next(),可以使用字符串、列表或元组对象来创建迭代器,迭代器对象可以使用正则 for 语句遍历或使用 next() 函数遍历。
具体的实例:
iter()函数与next()函数
List、tuple等都是可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。那么我们就可以在获取到的迭代器上不断的使用next()函数来获取下一条数据。 iter() 函数实际上调用了可迭代对象的 __iter__ 方法。
注意,当我们迭代完最后一个数据后,再次调用next()函数会抛出一个StopIteration异常,告诉我们所有的数据都已经迭代完了,next()函数不能再执行了。
lsit 生成式(列表生成式)
1、创建 list 的方式
经过我们之前的学习,我们都知道如何创建列表,但是在某些情况下,以赋值的形式创建列表太麻烦了,尤其是常规列表,一个一个写,一个一个赋值一方面,太麻烦了。比如生成一个有30个元素的列表,里面的元素是1-30,我们可以这样写:
输出的结果:
这个其实前面已经提过:比如有个打印九九乘法表的例子。这个方法实际上只是几行代码。可以参考上一篇文章:循环语句的使用
但是,如果你使用列表生成公式,你可以用一行代码生成一个九十九乘法表。具体看代码:
最后输出的结果:
不过,这里我们先要了解如何创建 list 生成式
2、list 生成式的创建
首先,lsit 生成式的语法为:
第一种语法:首先遍历iterable中的所有内容,每次迭代将iterable中对应的内容放入iter_var中,然后将iter_var中的内容应用到表达式中,最后使用表达式的计算值生成一个列表。
第二种语法:加入判断语句,只有iterable中对应的内容满足条件才放入iter_var,然后在表达式中应用iter_var的内容,最后生成一个list表达式的计算值。
其实不难理解,因为是列表生成,所以必须用[]括起来,然后里面的语句就是把要生成的元素放在前面,后面是for循环语句或者a for循环语句和判断语句。
例子:
输出的结果:
可以看出,把要生成的元素x * x放在前面,后面是for循环就可以创建列表。那么for循环之后的if形式呢?以及如何理解:
输出的结果:
这个例子是求1到10之间的偶数的平方根。上面说了x * x是要生成的元素,后面的部分其实是嵌套在for循环中的if判断语句。
那么有了这个知识点,我们也可以猜到for循环也是嵌套在for循环里面的。具体例子:
输出的结果:
其实知道列表生成是怎么组合的,就不难理解这个东西了。因为列表生成器只是结合了之前学过的知识点,换成了更简洁的写法。
生成器
使用迭代器,我们可以在每次迭代获取数据(通过next()方法)时,根据特定的规则生成数据。但是我们在实现迭代器的时候,需要记录当前迭代的状态,然后才能根据当前状态生成下一次数据。为了记录当前状态并与 next() 函数迭代使用,我们可以使用更简单的语法,即生成器。生成器是一种特殊的迭代器。
创建生成器的方法1
创建生成器的方法有很多种。第一种方法很简单,就是把一个列表生成表达式的[ ]改成( )
创建 L 和 G 之间的唯一区别是最外层的 [ ] 和 ( ) ,L 是列表而 G 是生成器。我们可以直接打印出列表L的每一个元素,而对于生成器G,我们可以像迭代器一样使用它,即通过next()函数、for循环、list()等方法。
创建生成器的方法2
发电机非常强大。如果计算算法比较复杂,不能用类似列表生成的for循环实现,也可以用函数实现。我们以著名的斐波那契数列为例,回忆一下上次我们是如何实现迭代器的:
请注意,在使用迭代器实现的方式中,我们需要使用几个变量(n、current、num1、num2)来保存迭代的状态。现在让我们用一个生成器来实现它。
迭代器和生成器综合例子
因为迭代器和生成器基本上是互通的,所以需要整合一些知识点
1、反向迭代
反向迭代也是一个常见的需求。比如从一开始迭代的例子中,输出列表中有一个元素,从1到5
那么我们从 5 到 1 呢?这也很简单, Python 中有内置的函数 reversed()
方向迭代很简单,可是要注意一点就是:
反向迭代仅仅当对象的大小可预先确定或者对象实现了 __reversed__() 的特殊方法时才能生效。 如果两者都不符合,那你必须先将对象转换为一个列表才行
其实很多时候我们可以通过在自定义类上实现__reversed__()方法来实现反向迭代。但是,有些知识点在前面的章节中没有提到,大家可以相应阅读。有编程基础的,学完以上知识点应该能看懂。
输出的结果是1比30,然后30比1,分别是顺印和反印
2、同时迭代多个序列
你希望同时遍历多个序列,每次从每个序列中取出一个元素。你遇到过这样的需求吗?
为了同时迭代多个序列,使用 zip() 函数,具体示例:
输出的结果:
事实上 zip(a, b) 生成一个迭代器,它返回元组 (x, y),其中 x 来自 a,y 来自 b。一旦其中一个序列结束,迭代就结束。因此,迭代长度与参数中的最短序列长度一致。注意理解这句话,也就是说如果a和b的长度不一致,就以最短的为准,遍历结束。
使用 zip() 函数,我们还可以从键列表和值列表生成 dict(字典),如下所示:
输出的结果:
这里要提一下,zip() 是一个参数,它可以接受两个以上的序列,而不仅仅是两个。
本文为原创文章,版权归知行编程网所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 如何用python画图08/20
- ♥ python中的and关键字是什么09/07
- ♥ python列表可以求平均值吗10/01
- ♥ python方法在列表中和列表末尾添加元素09/21
- ♥ pandas中join()的两种应用方法09/22
- ♥ 如何使用python定期获取网页内容10/21
内容反馈