1、生成器
我们知道,列表生成式生成的列表占在内存中。当列表的元素较少时还行,但是达到了一定的数量,就会非常的浪费内存,因为我们用的可能是其中很少的几个元素,其他的就闲置在那。而生成器就不一样了,他就像是一个函数一样,调用的时候,生成器才运行。所以,生成器节省了很大部分空间。每次调用生成器,它都会记住一个值,下次调用的时候,以上次的值为基准,推算出下一个值。生成器我们叫做generator。
(1)生成器的第一种创建方法:
a=( i for i in range(10))
print(a)
>>> <generator object <genexpr> at 0x000000000270A570>
(2)生成器 penerator
生成器的第一种创建方法类似列表生成式,只不过是把 [ ] 换成了 ( ) 。但是我们输出之后,结果并没有像列表生成式那样,返回一个 list 。next()函数是调用的方法。比如:
# generator 的第一种调用方法:
next(g)
# 实例1:
g = (x for x in range(10))
>>> next(g)
0
>>> next(g)
1
>>> next(g)
2
......
>>> next(g)
9
>>> next(g)
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
next(a)
StopIteration
# 我们只创建了 0 - 9 ,所以,超出后,就显示错误
但是这样的方法没有实用性,效率很低。我们可以试着用for循环调用一下,看可行不。
# 实例2
g = (x for x in range(10))
for i in g:
print(i,end=" ")
>>> 0 1 2 3 4 5 6 7 8 9
# 事实证明,可行。
(3)生成器 penerator 的第二种创建方法:
yield 返回值
yield 和 return 有相似之处,他们都由返回值的性质。但是yield有个特性,执行到 yield 语句的时候,就会停止并返回。下次接着从yield 语句处开始执行,再次遇到 yield,也会停止并返回。
# 实例3(非 generator)
def func(n):
for a in range(1,n):
b=a*a
print(b)
func(11)
>>>
1
4
9
16
25
36
49
64
81
100
# 实例4
# 我们把 print 更换为 yield ,这个函数就是 generator 了。
def func(n):
for a in range(1,n):
b=a*a
yield b
a=func(11)
# 为了明了,我们使用next函数调用看看。
next(a)
>>> 1
next(a)
>>> 4
next(a)
>>> 9
......
next(a)
>>> 100
# 结果是也一样的
# 实例5,我们也可以使用for循环来迭代
for i in a:
print(i,end=" ")
>>> 1 4 9 16 25 36 49 64 81 100
# 结果是一样的,只不过我们把换行符给替换掉了
2、迭代器
我们知道,能用 for 循环的,都是可迭代对象,包括 list、tuple、dict、set、str,还有刚讲的生成器(generator)。这些对象称为Iterable。
而迭代器是能被 next()函数调用的。所以,我们可以这么定义:所有可以作用于for循环,还能被next()函数调用的对象,就是迭代器,称为Iterator(廖雪峰老师那抄袭来的)
所有的迭代器(Iterator) 一定是可迭代对象 (Iterable),但是所有的可迭代对象(Iterator)不一定就是迭代器(Iterator)
但是,可迭代对象 list、dict、str可以转化为迭代器。
iter(list、dict、str)
# 实例
from collections import Iterator
isinstance(iter(‘Python‘),Iteraotr)
>>> True
关注公众号,了解更多!
原文:https://www.cnblogs.com/pyshadow/p/10400338.html