网络编程

python生成器

来源:http://www.xtcsyb.com 作者:永利402游戏网站-永利402com官方网站 时间:2019-11-09 10:53

写在序言

1.迭代

在知晓生成器早先,先精晓迭代。

每每会映注重帘,python函数中带有yield关键字,那么yield是怎么,有哪些效果与利益?

1.1 迭代

万生龙活虎给定叁个list或tuple,大家可以通过for循环来遍历这几个list或tuple,这种遍历大家誉为迭代(Iteration卡塔 尔(阿拉伯语:قطر‎

alist = [1, 2, 3, 4, 5]

for i in alist:
    print(i)

1
2
3
4
5

正如将列表中的成分通过for循环,遍历了整套alist列表,这种不重复地方便人民群众其内部的每三个子项的表现正是迭代。

 

1.2 可迭代对象

可以直接效果于for循环的对象统称为可迭代对象:Iterable,可迭代对象日常都完毕了__iter()__办法,可迭代对象通过其内建的方__iter()__归来八个迭代器对象。

a_iterable = [1, 2, 3]

a_iterator = iter(a_iterable)  # 将可迭代对象转化为迭代器

next(a_iterator)

1

next(a_iterator)

2

next(a_iterator)

3

答案:可以掌握yield是三个生成器;

1.3 迭代器

能够被next()函数调用并反复重返下贰个值的对象称为迭代器:Iterator,迭代器其内完毕了__iter__方法和__next__办法,for循环本质是经过调用可迭代对象的__iter__措施,该方法再次来到叁个迭代器对象,再用__next__方法遍历元素

概念一个迭代器:

class MyRange:
    def __init__(self, end):
        self.index = 0
        self.end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < self.end:
            val = self.index
            self.index += 1
            return val
        else:
            raise StopIteration()

my_range = MyRange(3)

print([i for i in my_range])

[0, 1, 2]

print([i for i in my_range])

[]

迭代器只可以迭代三遍,每回调用调用 next() 方法就能上前一步,不可能后退,所以当迭代器迭代到最后时,就无法重复使用,全部供给将迭代器和可迭代对象分别定义

校勘上面的可迭代对象:

class MyRange:
    def __init__(self, end):
        self.end = end

    def __iter__(self):
        return MyIterator(self.end)

class MyIterator:
    def __init__(self, end):
        self.index = 0
        self.end = end

    def __iter__(self):
        return self    

    def __next__(self):
        if self.index < self.end:
            val = self.index
            self.index += 1
            return val
        else:
            raise StopIteration()

my_range = MyRange(3)

print([i for i in my_range])

[0, 1, 2]

print([i for i in my_range])

[0, 1, 2]

功用:碰着yield关键字,函数会直接回到yield值,约等于return;分歧的是下一次调用的时候会从yield之后的代码开首推行。

2. 生成器

生成器与可迭代对象、迭代器的涉嫌

图片 1

图表来源于Iterables vs. Iterators vs. Generators

生成器对象,在每趟调用它的next()方法时回来三个值,直到它抛出StopInteration。

生成器是能够迭代的,然则你 只能读取它三次,因为它并不把富有的值放在内部存款和储蓄器中,它是实时地变化数据, 能够用生成器表明式创设:

my_generator = (x ** 2 for x in range(3))

my_generator

<generator object <genexpr> at 0x7f975b7a4af0>

for i in my_generator:
    print(i)

0
1
4

yield

能够写叁个日常的饱含yield语句的Python函数,Python会检查测试对yield的施用并将函数标志为五个生成器,当函数推行到yield语句时,像return语句那样再次来到一个值,可是解释器会保存对栈的引用,它会被用来在下二遍调用next时回涨函数。

def my_generator():
    yield 1
    yield 2
    yield 'a'
    yield 'generator'

g = my_generator()

g

<generator object my_generator at 0x7f975b7a4d58>

next(g)

1

next(g)

2

next(g)

'a'

next(g)

'generator'

next(g)

---------------------------------------------------------------------------

StopIteration                             Traceback (most recent call last)

<ipython-input-12-5f315c5de15b> in <module>()
----> 1 next(g)


StopIteration: 

地点的事例中,每一回调用next()最初实时地转移数据,并赶回,因而生成器只可读取三回,上次实施读取的值在下一次实行中就无法读取。当全部生成器的值都被读取后,在调用机相会世StopIteration的乖谬。

def my_gen():
    for i in range(5):
        yield i ** 3

my_gen()

<generator object my_gen at 0x7f975ae15a40>

mygen = my_gen()

for i in mygen:
    print(i)

0
1
8
27
64

每一趟试行到yield语句,则赶回二个值,再履行的时候从上次停下来的地点起首实行。yield语句保存了上次实践后的境况,后一次施行不是从头开始,而是从上次的状态起始。

当调用my_gen()那几个函数的时候,函数内部的代码不会马上施行,而是回到叁个生成器对象,当使用for循环进行遍历的时候,函数内部的代码开端实施,推行到yield表达式再次回到贰个值,记录当前情景并结束,下三遍的访谈时再从那几个状态开首试行。

举多少个不太合适的事例,普通的函数便是未有存档的娱乐,只要游戏带头,就玩到结尾,下一回再玩依旧从头开始,而生成器正是加了存档,后一次玩从上次存档的地方开头

 

有关生成器的思考

(瞎掰的。。。。卡塔尔国生成器到底起到哪边吗成效呢,尽管生成二个生成器对象,而生成器对象自然是二个迭代器,所以能够那样说,生成器再次来到了二个足以用for循环遍历所以子项,能够用next()方法访问下多少个子项,能够在做客时动态的成形数据而节省里部存款和储蓄器的对象。

生成器是怎么着?

阅读

全盘知道 Python 迭代对象、迭代器、生成器
对 Python 迭代的尖锐商量
Python迭代器和生成器
3. (译)Python关键字yield的解释(stackoverflow)
Python之列表生成式、生成器、可迭代对象与迭代器

是可以迭代的,可是你 只好够读取它叁次 ,因为它并不把持有的值放在内部存款和储蓄器中,它是实时地调换数据:

 

有人或然会说,作者直接迭代,遍历多好,为啥要用生成器,然后去遍历生成器,这多劳神。

这就是说您要打听,list列表,全部数据是积存在内存中的。如若数据量十分的大,会丰盛耗内部存款和储蓄器。

 

 

yield是多少个独树一帜的return?

不等的是实施进度中遭受yield关键字,会阻断,yield 再次来到的是一个生成器。

第贰回迭代中您的函数会施行,从起首到达 yield 关键字,然后再次来到 yield 后的值作为第一遍迭代的归来值.

下一场,每一趟实施那些函数都会继续实行你在函数内部定义的这几个循环的下一遍,再回去那些值,直到未有得以回到的。

 

专心,当函数中现身yield,该函数重回的正是一个生成器。不在是置身事外函数。

def func(num):
    n,a,b = 0,0,1
    while num > n:
        yield b  #阻断,返回b
        a,b = b,a + b
        n+=1

for i in  func(19): #func(19)是一个生成器,生成器只有调用时执行一次。所以这里用循环
    print i

 

除却for循环取值,你也足以因而next()来取下叁个值。

t = func(19)
t.next()

 

本文由永利402游戏网站-永利402com官方网站发布于网络编程,转载请注明出处:python生成器

关键词: