您的位置:

包含python生成器迭代实际案例的词条

本文目录一览:

python 迭代器和生成器的区别

Num01–迭代器

定义:

对于list、string、tuple、dict等这些容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()函数。iter()是python内置函数。

iter()函数会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内的元素。next()也是python内置函数。在没有后续元素时,next()会抛出一个StopIteration异常,通知for语句循环结束。

迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数的时候,调用的就是迭代器对象的_next_方法(Python3中是对象的_next_方法,Python2中是对象的next()方法)。所以,我们要想构造一个迭代器,就要实现它的_next_方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现_iter_方法,而_iter_方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的_iter_方法返回自身self即可。

一些术语的解释:

1,迭代器协议:对象需要提供next()方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代。

2,可迭代对象:实现了迭代器协议对象。list、tuple、dict都是Iterable(可迭代对象),但不是Iterator(迭代器对象)。但可以使用内建函数iter(),把这些都变成Iterable(可迭代器对象)。

3,for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束

Python自带容器对象案例:

# 随便定义一个listlistArray=[1,2,3]# 使用iter()函数iterName=iter(listArray)

print(iterName)# 结果如下:是一个列表list的迭代器# list_iterator object at 0x0000017B0D984278print(next(iterName))

print(next(iterName))

print(next(iterName))

print(next(iterName))#没有迭代到下一个元素,直接抛出异常# 1# 2# 3# Traceback (most recent call last):# File "Test07.py", line 32, in module# StopIteration123456789101112131415161718

Python中一个实现了_iter_方法和_next_方法的类对象,就是迭代器,如下案例是计算菲波那切数列的案例

class Fib(object):

def __init__(self, max):

super(Fib, self).__init__()

self.max = max def __iter__(self):

self.a = 0

self.b = 1

return self def __next__(self):

fib = self.a if fib self.max: raise StopIteration

self.a, self.b = self.b, self.a + self.b return fib# 定义一个main函数,循环遍历每一个菲波那切数def main():

# 20以内的数

fib = Fib(20) for i in fib:

print(i)# 测试if __name__ == '__main__':

main()12345678910111213141516171819202122232425262728

解释说明:

在本类的实现中,定义了一个_iter_(self)方法,这个方法是在for循环遍历时被iter()调用,返回一个迭代器。因为在遍历的时候,是直接调用的python内置函数iter(),由iter()通过调用_iter_(self)获得对象的迭代器。有了迭代器,就可以逐个遍历元素了。而逐个遍历的时候,也是使用内置的next()函数通过调用对象的_next_(self)方法对迭代器对象进行遍历。所以要实现_iter_(self)和_next_(self)这两个方法。

而且因为实现了_next_(self)方法,所以在实现_iter_(self)的时候,直接返回self就可以。

总结一句话就是:

在循环遍历自定义容器对象时,会使用python内置函数iter()调用遍历对象的_iter_(self)获得一个迭代器,之后再循环对这个迭代器使用next()调用迭代器对象的_next_(self)。

注意点:_iter_(self)只会被调用一次,而_next_(self)会被调用 n 次,直到出现StopIteration异常。

Num02–生成器

作用:

延迟操作。也就是在需要的时候才产生结果,不是立即产生结果。12

注意事项:

生成器是只能遍历一次的。

生成器是一类特殊的迭代器。123

分类:

第一类:生成器函数:还是使用 def 定义函数,但是,使用yield而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行。

如下案例加以说明:

# 菲波那切数列def Fib(max):

n, a, b = 0, 0, 1

while n max: yield b

a, b = b, a + b

n = n + 1

return '亲!没有数据了...'# 调用方法,生成出10个数来f=Fib(10)# 使用一个循环捕获最后return 返回的值,保存在异常StopIteration的value中while True: try:

x=next(f)

print("f:",x) except StopIteration as e:

print("生成器最后的返回值是:",e.value) break123456789101112131415161718

第二类:生成器表达式:类似于列表

,只不过是把一对大括号[]变换为一对小括号()。但是,生成器表达式是按需产生一个生成器结果对象,要想拿到每一个元素,就需要循环遍历。

如下案例加以说明:

# 一个列表xiaoke=[2,3,4,5]# 生成器generator,类似于list,但是是把[]改为()gen=(a for a in xiaoke)for i in gen:

print(i)#结果是:2345# 为什么要使用生成器?因为效率。# 使用生成器表达式取代列表推导式可以同时节省 cpu 和 内存(RAM)。# 如果你构造一个列表(list)的目的仅仅是传递给别的函数,# 比如 传递给tuple()或者set(), 那就用生成器表达式替代吧!# 本案例是直接把列表转化为元组kk=tuple(a for a in xiaoke)

print(kk)#结果是:(2, 3, 4, 5)# python内置的一些函数,可以识别这是生成器表达式,外面有一对小括号,就是生成器result1=sum(a for a in range(3))

print(result1)# 列表推导式result2=sum([a for a in range(3)])

print(result2)

python 如何使用生成器函数实现可迭代对象

Iamlaosong文

我们在用for ... in ...语句循环时,in后面跟随的对象要求是可迭代对象,即可以直接作用于for循环的对象统称为可迭代对象(Iterable),如list、tuple、dict、set、str等。

可迭代对象是实现了__iter__()方法的对象,而迭代器(Iterator)则是实现了__iter__()和__next__()方法的对象,可以显示地获取下一个元素。这种可以被next调用并不断返回下一个值的对象称为迭代器。迭代器一定是可迭代对象,反过来则不一定成立。用iter()函数可以把list、dict、str等Iterable变成Iterator,例如:

bb=[x for x in range(10)]

cc=iter(bb)

cc.next()

循环变量的值其实可以看着是一次次用next取值的过程,每取一个值,做一次处理。list等对象用于循环实际上可以看着是用iter()方法产生一个迭代器,然后循环取值。

生成器(generator)就是一个能返回迭代器的函数,其实就是定义一个迭代算法,可以理解为一个特殊的迭代器。调用这个函数就得到一个迭代器,生成器中的yield相当于一个断点,执行到此返回一个值后暂停,从而实现next取值。

Python中的“迭代”详解

迭代器模式:一种惰性获取数据项的方式,即按需一次获取一个数据项。

所有序列都是可以迭代的。我们接下来要实现一个 Sentence(句子)类,我们向这个类的构造方法传入包含一些文本的字符串,然后可以逐个单词迭代。

接下来测试 Sentence 实例能否迭代

序列可以迭代的原因:

iter()

解释器需要迭代对象 x 时,会自动调用iter(x)。

内置的 iter 函数有以下作用:

由于序列都实现了 __getitem__ 方法,所以都可以迭代。

可迭代对象:使用内置函数 iter() 可以获取迭代器的对象。

与迭代器的关系:Python 从可迭代对象中获取迭代器。

下面用for循环迭代一个字符串,这里字符串 'abc' 是可迭代的对象,用 for 循环迭代时是有生成器,只是 Python 隐藏了。

如果没有 for 语句,使用 while 循环模拟,要写成下面这样:

Python 内部会处理 for 循环和其他迭代上下文(如列表推导,元组拆包等等)中的 StopIteration 异常。

标准的迭代器接口有两个方法:

__next__ :返回下一个可用的元素,如果没有元素了,抛出 StopIteration 异常。

__iter__ :返回 self,以便在需要使用可迭代对象的地方使用迭代器,如 for 循环中。

迭代器:实现了无参数的 __next__ 方法,返回序列中的下一个元素;如果没有元素了,那么抛出 StopIteration 异常。Python 中的迭代器还实现了 __iter__ 方法,因此迭代器也可以迭代。

接下来使用迭代器模式实现 Sentence 类:

注意, 不要 在 Sentence 类中实现 __next__ 方法,让 Sentence 实例既是可迭代对象,也是自身的迭代器。

为了“支持多种遍历”,必须能从同一个可迭代的实例中获取多个独立的迭代器,而且各个迭代器要能维护自身的内部状态,因此这一模式正确的实现方式是,每次调用 iter(my_iterable) 都新建一个独立的迭代器。

所以总结下来就是:

实现相同功能,但却符合 Python 习惯的方式是,用生成器函数代替 SentenceIteror 类。

只要 Python 函数的定义体中有 yield 关键字,该函数就是生成器函数。调用生成器函数,就会返回一个生成器对象。

生成器函数会创建一个生成器对象,包装生成器函数的定义体,把生成器传给 next(...) 函数时,生成器函数会向前,执行函数定义体中的下一个 yield 语句,返回产出的值,并在函数定义体的当前位置暂停,。最终,函数的定义体返回时,外层的生成器对象会抛出 StopIteration 异常,这一点与迭代器协议一致。

如今这一版 Sentence 类相较之前简短多了,但是还不够慵懒。 惰性 ,是如今人们认为最好的特质。惰性实现是指尽可能延后生成值,这样做能节省内存,或许还能避免做无用的处理。

目前实现的几版 Sentence 类都不具有惰性,因为 __init__ 方法急迫的构建好了文本中的单词列表,然后将其绑定到 self.words 属性上。这样就得处理整个文本,列表使用的内存量可能与文本本身一样多(或许更多,取决于文本中有多少非单词字符)。

re.finditer 函数是 re.findall 函数的惰性版本,返回的是一个生成器,按需生成 re.MatchObject 实例。我们可以使用这个函数来让 Sentence 类变得懒惰,即只在需要时才生成下一个单词。

标准库提供了很多生成器函数,有用于逐行迭代纯文本文件的对象,还有出色的 os.walk 函数等等。本节专注于通用的函数:参数为任意的可迭代对象,返回值是生成器,用于生成选中的、计算出的和重新排列的元素。

第一组是用于 过滤 的生成器函数:从输入的可迭代对象中产出元素的子集,而且不修改元素本身。这种函数大多数都接受一个断言参数(predicate),这个参数是个 布尔函数 ,有一个参数,会应用到输入中的每个元素上,用于判断元素是否包含在输出中。

以下为这些函数的演示:

第二组是用于映射的生成器函数:在输入的单个/多个可迭代对象中的各个元素上做计算,然后返回结果。

以下为这些函数的用法:

第三组是用于合并的生成器函数,这些函数都可以从输入的多个可迭代对象中产出元素。

以下为演示:

第四组是从一个元素中产出多个值,扩展输入的可迭代对象。

以下为演示:

第五组生成器函数用于产出输入的可迭代对象中的全部元素,不过会以某种方式重新排列。

下面的函数都接受一个可迭代的对象,然后返回单个结果,这种函数叫“归约函数”,“合拢函数”或“累加函数”,其实,这些内置函数都可以用 functools.reduce 函数实现,但内置更加方便,而且还有一些优点。

参考教程:

《流畅的python》 P330 - 363

如何更好地理解Python迭代器和生成器

Python这门语言中,生成器毫无疑问是最有用的特性之一。与此同时,也是使用的最不广泛的Python特

性之一。究其原因,主要是因为,在其他主流语言里面没有生成器的概念。正是由于生成器是一

个“新”的东西,所以,它一方面没有引起广大工程师的重视,另一方面,也增加了工程师的学习成本,

最终导致大家错过了Python中如此有用的一个特性。

我的这篇文章,希望通过简单易懂的方式,深入浅出地介绍Python的生成器,以改变“如此有用的特性却

使用极不广泛”的现象。本文的组织如下:在第1章,我们简单地介绍了Python中的迭代器协议;在本文

第2章,将会详细介绍生成器的概念和语法;在第3章,将会给出一个有用的例子,说明使用生成器的好

处;在本文最后,简单的讨论了使用生成器的注意事项。

1. 迭代器协议

由于生成器自动实现了迭代器协议,而迭代器协议对很多人来说,也是一个较为抽象的概念。所以,为了

更好的理解生成器,我们需要简单的回顾一下迭代器协议的概念。

1. 迭代器协议是指:对象需要提供next方法,它要么返回迭代中的下一项,要么就引起一个

StopIteration异常,以终止迭代

2. 可迭代对象就是:实现了迭代器协议的对象

3. 协议是一种约定,可迭代对象实现迭代器协议,Python的内置工具(如for循环,sum,min,max函

数等)使用迭代器协议访问对象。

举个例子:在所有语言中,我们都可以使用for循环来遍历数组,Python的list底层实现是一个数组,所

以,我们可以使用for循环来遍历list。如下所示:

for n in [1, 2, 3, 4]:

... print n

但是,对Python稍微熟悉一点的朋友应该知道,Python的for循环不但可以用来遍历list,还可以用来遍历

文件对象,如下所示:

with open(‘/etc/passwd’) as f: # 文件对象提供迭代器协议

... for line in f: # for循环使用迭代器协议访问文件

... print line

...

为什么在Python中,文件还可以使用for循环进行遍历呢?这是因为,在Python中,文件对象实现了迭代

器协议,for循环并不知道它遍历的是一个文件对象,它只管使用迭代器协议访问对象即可。正是由于

Python的文件对象实现了迭代器协议,我们才得以使用如此方便的方式访问文件,如下所示:

f = open('/etc/passwd')

dir(f)

['__class__', '__enter__', '__exit__', '__iter__', '__new__', 'writelines', '...'

2. 生成器

Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产

生结果。这也是生成器的主要好处。

Python有两种不同的方式提供生成器:

2017/11/6 如何更好地理解Python迭代器和生成器? - 知乎

2/5

1. 生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一

个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行

2. 生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个

结果列表

2.1 生成器函数

我们来看一个例子,使用生成器返回自然数的平方(注意返回的是多个值):

def gensquares(N):

for i in range(N):

yield i ** 2

for item in gensquares(5):

print item,

使用普通函数:

def gensquares(N):

res = []

for i in range(N):

res.append(i*i)

return res

for item in gensquares(5):

print item,

可以看到,使用生成器函数代码量更少。

2.2 生成器表达式

使用列表推导,将会一次产生所有结果:

squares = [x**2 for x in range(5)]

squares

[0, 1, 4, 9, 16]

将列表推导的中括号,替换成圆括号,就是一个生成器表达式:

squares = (x**2 for x in range(5))

squares next(squares)

next(squares)

1

next(squares)

4

list(squares)

[9, 16]

Python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象

的。例如, sum函数是Python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协

2017/11/6 如何更好地理解Python迭代器和生成器? - 知乎

3/5

议,所以,我们可以直接这样计算一系列值的和:

sum(x ** 2 for x in xrange(4))

而不用多此一举的先构造一个列表:

sum([x ** 2 for x in xrange(4)])

2.3 再看生成器

前面已经对生成器有了感性的认识,我们以生成器函数为例,再来深入探讨一下Python的生成器:

1. 语法上和函数类似:生成器函数和常规函数几乎是一样的。它们都是使用def语句进行定义,差别在

于,生成器使用yield语句返回一个值,而常规函数使用return语句返回一个值

2. 自动实现迭代器协议:对于生成器,Python会自动实现迭代器协议,以便应用到迭代背景中(如for

循环,sum函数)。由于生成器自动实现了迭代器协议,所以,我们可以调用它的next方法,并且,

在没有值可以返回的时候,生成器自动产生StopIteration异常

3. 状态挂起:生成器使用yield语句返回一个值。yield语句挂起该生成器函数的状态,保留足够的信息,

以便之后从它离开的地方继续执行

3. 示例

我们再来看两个生成器的例子,以便大家更好的理解生成器的作用。

首先,生成器的好处是延迟计算,一次返回一个结果。也就是说,它不会一次生成所有的结果,这对于大

数据量处理,将会非常有用。

大家可以在自己电脑上试试下面两个表达式,并且观察内存占用情况。对于前一个表达式,我在自己的电

脑上进行测试,还没有看到最终结果电脑就已经卡死,对于后一个表达式,几乎没有什么内存占用。

sum([i for i in xrange(10000000000)])

sum(i for i in xrange(10000000000))

除了延迟计算,生成器还能有效提高代码可读性。例如,现在有一个需求,求一段文字中,每个单词出现

的位置。

不使用生成器的情况:

def index_words(text):

result = []

if text:

result.append(0)

for index, letter in enumerate(text, 1):

if letter == ' ':

result.append(index)

return result

使用生成器的情况:

2017/11/6 如何更好地理解Python迭代器和生成器? - 知乎

4/5

def index_words(text):

if text:

yield 0

for index, letter in enumerate(text, 1):

if letter == ' ':

yield index

这里,至少有两个充分的理由说明 ,使用生成器比不使用生成器代码更加清晰:

1. 使用生成器以后,代码行数更少。大家要记住,如果想把代码写的Pythonic,在保证代码可读性的前

提下,代码行数越少越好

2. 不使用生成器的时候,对于每次结果,我们首先看到的是result.append(index),其次,才是index。

也就是说,我们每次看到的是一个列表的append操作,只是append的是我们想要的结果。使用生成

器的时候,直接yield index,少了列表append操作的干扰,我们一眼就能够看出,代码是要返回

index。

这个例子充分说明了,合理使用生成器,能够有效提高代码可读性。只要大家完全接受了生成器的概念,

理解了yield语句和return语句一样,也是返回一个值。那么,就能够理解为什么使用生成器比不使用生成

器要好,能够理解使用生成器真的可以让代码变得清晰易懂。

4. 使用生成器的注意事项

相信通过这篇文章,大家已经能够理解生成器的作用和好处。但是,还没有结束,使用生成器,也有一点

注意事项。

我们直接来看例子,假设文件中保存了每个省份的人口总数,现在,需要求每个省份的人口占全国总人口

的比例。显然,我们需要先求出全国的总人口,然后在遍历每个省份的人口,用每个省的人口数除以总人

口数,就得到了每个省份的人口占全国人口的比例。

如下所示:

def get_province_population(filename):

with open(filename) as f:

for line in f:

yield int(line)

gen = get_province_population('data.txt')

all_population = sum(gen)

#print all_population

for population in gen:

print population / all_population

执行上面这段代码,将不会有任何输出,这是因为,生成器只能遍历一次。在我们执行sum语句的时候,

就遍历了我们的生成器,当我们再次遍历我们的生成器的时候,将不会有任何记录。所以,上面的代码不

会有任何输出。

因此,生成器的唯一注意事项就是:生成器只能遍历一次。

5. 总结

2017/11/6 如何更好地理解Python迭代器和生成器? - 知乎

5/5

本文深入浅出地介绍了Python中,一个容易被大家忽略的重要特性,即Python的生成器。为了讲解生成

器,本文先介绍了迭代器协议,然后介绍了生成器函数和生成器表达式,并通过示例演示了生成器的优点

和注意事项。在实际工作中,充分利用Python生成器,不但能够减少内存使用,还能够提高代码可读性。

掌握生成器也是Python高手的标配。希望本文能够帮助大家理解Python的生成器

Python基础之迭代器

一.什么是迭代器

迭代器是用来迭代取值的工具。

而涉及到把多个值循环取出来的类型有:列表,字符串,元组,字段,集合,打开文件等。通过使用的遍历方式有for···in···,while等,但是,这些方式只适用于有索引的数据类型。为了解决索引取的局限性,python提供了一种 不依赖于索引的取值方式:迭代器

注意:

二.可迭代对象

可迭代对象:但凡内置有__iter__方法的都称为可迭代对象

常见的可迭代对象:

1.集合数据类型,如list,tuple,dict,set,str等

2.生成器,包括生成器和带yield的生成器函数。

三.如何创建迭代器

迭代器是一个包含数个值的对象。

迭代器是可以迭代的对象,这意味着您可以遍历所有值。

从技术上讲,在Python中,迭代器是实现迭代器协议的对象,该协议由方法 __iter__() 和 __next__() 组成。

简而言之,一个类里面实现了__iter__()和__next__()这两个魔法方法,那么这个类的对象就是可迭代对象。

四.迭代器的优缺点

1.优点

2.缺点

五.迭代器示例

另外,如果类Stu继承了Iterator,那么Stu可以不用实现__iter__()方法

遍历迭代器

StopIteration

如果你有足够的 next() 语句,或者在 for 循环中使用,则上面的例子将永远进行下去。

为了防止迭代永远进行,我们可以使用 StopIteration 语句。

在 __next__() 方法中,如果迭代完成指定的次数,我们可以添加一个终止条件来引发错误

闲话python 45: 浅谈生成器yield

生成器似乎并不是一个经常被开发者讨论的语法,因此也就没有它的大兄弟迭代器那么著名。大家不讨论它并不是说大家都已经对它熟悉到人尽皆知,与之相反,即使是工作多年的开发者可能对生成器的运行过程还是知之甚少。这是什么原因导致的呢?我猜想大概有以下几点原因: (1)运行流程不同寻常,(2)日常开发不需要,(3)常常将生成器与迭代器混淆。 生成器的运行流程可以按照协程来理解,也就是说 返回中间结果,断点继续运行 。这与我们通常对于程序调用的理解稍有差异。这种运行模式是针对什么样的需求呢? 一般而言,生成器是应用于大量磁盘资源的处理。 比如一个很大的文件,每次读取一行,下一次读取需要以上一次读取的位置为基础。下面就通过代码演示具体看看生成器的运行机制、使用方式以及与迭代器的比较。

什么是生成器?直接用文字描述可能太过抽象,倒不如先运行一段代码,分析这段代码的运行流程,然后总结出自己对生成器的理解。

从以上演示可以看出,这段代码定义了一个函数,这个函数除了yield这个关键字之外与一般函数并没有差异,也就是说生成器的魔法都是这个yield关键字引起的。 第一点,函数的返回值是一个生成器对象。 上述代码中,直接调用这个看似普通的函数,然后将返回值打印出来,发现返回值是一个对象,而并不是普通函数的返回值。 第二点,可以使用next对这个生成器对象进行操作 。生成器对象天然的可以被next函数调用,然后返回在yield关键字后面的内容。 第三,再次调用next函数处理生成器对象,发现是从上次yield语句之后继续运行,直到下一个yield语句返回。

生成器的运行流程确实诡异,下面还要演示一个生成器可以执行的更加诡异的操作:运行过程中向函数传参。

返回生成器和next函数操作生成器已经并不奇怪了,但是在函数运行过程中向其传参还是让人惊呆了。 调用生成器的send函数传入参数,在函数内使用yield语句的返回值接收,然后继续运行直到下一个yield语句返回。 以前实现这种运行流程的方式是在函数中加上一个从控制台获取数据的指令,或者提前将参数传入,但是现在不用了,send方式使得传入的参数可以随着读取到的参数变化而变化。

很多的开发者比较容易混淆生成器和迭代器,而迭代器的运行过程更加符合一般的程序调用运行流程,因此从亲进度和使用熟悉度而言,大家对迭代器更有好感。比如下面演示一个对迭代器使用next方法进行操作。

从以上演示来看,大家或许会认为迭代器比生成器简单易用得太多了。不过,如果你了解迭代器的实现机制,可能就不会这么早下结论了。python内置了一些已经实现了的迭代器使用确实方便,但是如果需要自己去写一个迭代器呢?下面这段代码就带大家见识以下迭代器的实现。

在python中,能被next函数操作的对象一定带有__next__函数的实现,而能够被迭代的对象有必须实现__iter__函数。看了这么一段操作,相信大家对迭代器实现的繁琐也是深有体会了,那么生成器的实现是不是会让你觉得更加简单易用呢?不过千万别产生一个误区,即生成器比迭代器简单就多用生成器。 在实际开发中,如果遇到与大量磁盘文件或者数据库操作相关的倒是可以使用生成器。但是在其他的任务中使用生成器难免有炫技,并且使逻辑不清晰而导致可读性下降的嫌疑。 这大概也能解释生成器受冷落的原因。不过作为一个专业的开发者,熟悉语言特性是分内之事。

到此,关于生成器的讨论就结束了。本文的notebook版本文件在github上的cnbluegeek/notebook仓库中共享,欢迎感兴趣的朋友前往下载。