Python生成器与迭代器怎么用
这篇文章给大家分享的是有关Python生成器与迭代器怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
1、生成器
现在可以通过生成器来直接创建一个列表,但是由于内存的限制,列表的容量肯定是有限的,如果我们需要一个包含几百个元素的列表,但是每次访问的时候只访问其中的几个,那剩下的元素不使用就很浪费内存空间。
这个时候生成器(Generator
)就起到了作用,他是按照某种算法不断生成新的数据,直到满足某一个指定的条件结束
得到生成式的方式有如下几种:
通过列表生成式来得到生成器,示例代码如下:
g = (x for x in range(10)) # 将列表生成列的[]改变成为()# 打印其类型print(type(g)) # <class 'generator'># 调用其元素print(g.__next__()) # 0print(g.__next__()) # 1print(g.__next__()) # 2print(g.__next__()) # 3print(g.__next__()) # 4# 使用.__next__的方式调用print(next(g)) # 5print(next(g)) # 6print(next(g)) # 7print(next(g)) # 8print(next(g)) # 9# 使用next()的方法调用print(next(g)) # 当数据调用不到时会报出错误 StopIteration
需要多少调用多少,不调用的不会生成,也就不会占用内存空间,可以使用循环结构来按照需要来调用
g = (x for x in range(10)) # 将列表生成列的[]改变成为()skip = True # 判断条件count = 0 # 调用次数while skip: count += 1 # 循环一次+1 print(next(g)) if count > 9: break # 跳出循环
使用函数借助yield
关键字来完成一个生成器,生成斐波那契数列的前20个数,示例代码如下:
def fun(length): a, b = 0, 1 for _ in range(length): a, b = b, a + b yield afib = fun(20)print(type(fib)) # <class 'generator'> # 打印类型count = 0while count < 20: # 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 print(next(fib), "", end="") count += 1
流程如下:
在执行过程中,遇到yield
关键字就会暂停执行,下次调用则继续从上次暂停的位置继续执行,因为是一个循环语句,所有会直接跳到for
语句
如果在调用yield
,需要给它传值,就要使用.send()
方法了。
示例代码如下:
def fun(num): n = 0 for i in range(num + 1): n += i ret = yield n print(f"这是+到{ret}的第{i + 1} 次")g = fun(3)print(g.send(None))print(g.send('3'))print(g.send('3'))print(g.send('3'))'''---输出结果---0这是+到 3 的第 1 次1这是+到 3 的第 2 次3这是+到 3 的第 3 次6'''
send
的加入可以使生成器更加灵活,但是需要注意的是第一次调用生成器的send()
方法时,参数只能为None
,否则会抛出异常。当然也可以在调用send()
方法之前先调用一次next()
方法,目的是让生成器先进入yield
表达式。
2、迭代器与可迭代的生成器
可迭代的对象有生成器、元组、列表、集合、字典和字符串等
通过collections
的Iterable
函数结合isinstance
(object, classinfo)来判断一个对象时不是可迭代的对象
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。很生成器也是迭代器。
可以被next ()
函数调用并不断返回下一个值的对象称为迭代器: Iterator
,可以使用isinstance()
判断一个对象是否是Iterator
对象:
注意:可迭代的不一定是生成器,但是生成器一定第可迭代的。
把元组、列表、集合、字典和字符串等Iterable
变成Iterator
可以使用iter()
函数
Iterable
和Iterator****
的区别是Iterable
是可以作为for
循环对象的统称;而Iterator
对象需要被next()函数调用才不断返回下一个数据,直到没有数据时抛出StopIteration
错误,而在这之前是不会知道其长度的,所以Iterator的计算是惰性的,只有next()
函数叫他才会返回结果,Iterator
甚至可以表示一个无限大的数据流,例如全体自然数。
from collections.abc import Iterable, Iteratora = [1, 2, 3]b = {1, 2, 3}c = (1, 2, 3)d = "123"e = 123f = (x for x in range(5))# 打印数据类型print(type(a)) # <class 'list'>print(type(b)) # <class 'set'>print(type(c)) # <class 'tuple'>print(type(d)) # <class 'str'>print(type(e)) # <class 'int'>print(type(f)) # <class 'generator'>print("-" * 20)# 打印是否为可迭代对象print(isinstance(a, Iterable)) # Trueprint(isinstance(b, Iterable)) # Trueprint(isinstance(c, Iterable)) # Trueprint(isinstance(d, Iterable)) # Trueprint(isinstance(e, Iterable)) # Falseprint(isinstance(f, Iterable)) # Trueprint("-" * 20)# 除了字符串都是可迭代对象# 打印是否是迭代器print(isinstance(a, Iterator)) # Falseprint(isinstance(b, Iterator)) # Falseprint(isinstance(c, Iterator)) # Falseprint(isinstance(d, Iterator)) # Falseprint(isinstance(f, Iterator)) # True# 只有f(生成器)是迭代器print("-" * 20)# 通过iter()将可迭代转换为迭代器print(isinstance(iter(a), Iterator)) # Trueprint(isinstance(iter(b), Iterator)) # Trueprint(isinstance(iter(c), Iterator)) # Trueprint(isinstance(iter(d), Iterator)) # True
感谢各位的阅读!关于“Python生成器与迭代器怎么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341