python3迭代器和生成器

avatar 2020年5月3日23:04:06 1 1,139 次浏览

迭代函数就是一个利用for...in来完成的一个过程,但是呢?在没说迭代函数之前我们需要了解一下什么是迭代器,什么是生成器,两者的区别是什么,先一个一个的学习。

迭代器

先学习一下什么是迭代器,迭代器就是记录每次数据的访问,以及返回下次的数据,通过__next__()方法取得下一个指向的值。迭代器也称迭代对象,可以通过for .. in ..等语句将数据显示出来,这样的过程叫迭代。把数据显示的对象,我们称之为迭代对象。看下面的例子:

#!/usr/bin/python3
#coding:utf-8
#~~~~~~~~~~~~www.wulaoer.org 吴老二个人博客~~~~~~~
devops=["python3","k8s","nginx","mysql"]
wulaoer = iter(devops)
print ("输出迭代的第一个对象:",next(wulaoer))
print ("输出迭代的第二个对象:",next(wulaoer))

输出结果:

输出迭代的第一个对象: python3
输出迭代的第二个对象: k8s

迭代器的创建对象有两种分别是iter() 和 next(),上面我们使用的iter()创建的迭代对象,第一次打印的时候是第一个迭代对象"python3",第二次迭代的时候打印的是"k8s"。也可以使用for循环进行打印所有的迭代对象。看下面的例子:

#!/usr/bin/python3
#coding:utf-8
#~~~~~~~~~~~~www.wulaoer.org 吴老二个人博客~~~~~~~
devops=["python3","k8s","nginx","mysql"]
wulaoer = iter(devops)
for i in wulaoer:
    print("打印每一个迭代对象:",i)

输出结果:

打印每一个迭代对象: python3
打印每一个迭代对象: k8s
打印每一个迭代对象: nginx
打印每一个迭代对象: mysql

这是列表作为一个迭代对象举例的方法,常使用的其他迭代对象还有元祖,字典,字符串,set集合等。如果判断一个对象是否是迭代对象,可以使用collections模块的Iterable类型进行判断。例如:

#!/usr/bin/python3
#coding:utf-8
#~~~~~~~~~~~~www.wulaoer.org 吴老二个人博客~~~~~~~
from collections import Iterable
print("判断字符串是否是迭代对象:",isinstance("python3",Iterable))
print("判断列表是否是迭代对象:",isinstance(["python3","k8s","nginx"],Iterable))
print("判断整数是否是迭代对象:",isinstance(27,Iterable))

输出结果:

判断字符串是否是迭代对象: True
判断列表是否是迭代对象: True
判断整数是否是迭代对象: False

返回True就可以判断对象是迭代对象,False就不是迭代对象。我们可以使用迭代器生成一个有规律的数据,而不在使用已有的数据集取数,避免内存资源浪费。下面看个例子:

#!/usr/bin/python3
#coding:utf-8
#~~~~~~~~~~~~www.wulaoer.org 吴老二个人博客~~~~~~~
class Wulaoer:
    def __iter__(self):
        self.a = 1
        return self
    def __next__(self):
        if self.a <= 10:
            x = self.a
            self.a += 1
            return x
        else:
            raise StopIteration

wolf = Wulaoer()
myiter = iter(wolf)
for i in myiter:
    print("打印可迭代的对象:",i)

输出结果:

打印可迭代的对象: 1
打印可迭代的对象: 2
打印可迭代的对象: 3
打印可迭代的对象: 4
打印可迭代的对象: 5
打印可迭代的对象: 6
打印可迭代的对象: 7
打印可迭代的对象: 8
打印可迭代的对象: 9
打印可迭代的对象: 10

完成10次循环后,会触发StopIteration结束迭代。如果我们需要打印10以内的偶数,可以做一个判断,也就能根据我们的需要,打印指定的数据,这就是迭代器的好处。

生成器

生成器就是一个返回可以迭代对象的函数,在函数中使用了yield关键字,可以实现一个简单的生成器,此时的函数就变成了一个生成器函数。yield与return返回相同的值,两者的区别是return返回后,终止函数,而yield会保存当前函数执行的状态,在返回后,函数又回道之前保存的状态继续执行。看下面的生成器的例子:

#!/usr/bin/python3
#coding:utf-8
#~~~~~~~~~~~~www.wulaoer.org 吴老二个人博客~~~~~~~
def wulaoer():
    yield 1
    yield 2
    yield 3
wolf = wulaoer()
print("生成器函数",wolf)
print("打印生成器第一次返回值",wolf.__next__())
print("打印生成器第二次返回值",wolf.__next__())

输出结果:

生成器函数 <generator object wulaoer at 0x1013859e8>
打印生成器第一次返回值 1
打印生成器第二次返回值 2

生成器函数中一般包含一个或多个yield,当调用生成器函数时,函数将返回一个对象,但是不回立刻向下执行,像__iter__()和__next__()方法等是自动实现的,所以我嘛可以通过next()方法对对象进行迭代,一旦函数被yield,函数回被暂停,控制权繁华调用者,局部变量和它们的状态会被爆出,直到下一次调用,函数终止的时候,StopIteraion会被自动抛出。下面看生成器的表达式:

#!/usr/bin/python3
#coding:utf-8
#~~~~~~~~~~~~www.wulaoer.org 吴老二个人博客~~~~~~~
egg_list=[]
for i in range(10):
    egg_list.append('devops%s' %i)
print(egg_list)
# 使用三元表达式替换如上代码
l=['devops%s' %i for i in range(10)]
print(l)
l1=['devops%s' %i for i in range(10) if i > 5 ]
print(l1)
l3=['devops%s' %i for i in range(10) if i < 5]
print(l3)

输出结果:

['devops0', 'devops1', 'devops2', 'devops3', 'devops4', 'devops5', 'devops6', 'devops7', 'devops8', 'devops9']
['devops0', 'devops1', 'devops2', 'devops3', 'devops4', 'devops5', 'devops6', 'devops7', 'devops8', 'devops9']
['devops6', 'devops7', 'devops8', 'devops9']
['devops0', 'devops1', 'devops2', 'devops3', 'devops4']

下面看看生成器和迭代器的区别:

1、语法方面来讲:

生成器是用函数中yield语句来创建的。迭代器的创建首先跟函数无关,可以用iter([1,2])来创建。

2、使用方面来讲:

由于生成器是使用函数的方式创建的,所以生成器里面的所有过程都会被执行,但请注意生成器里面的过程只有在被next()调用或者for循环调用时,里面的过程才会被执行,如同上面的例子只是单纯调用add这个对象时,add里面的过程没有被执行哦

迭代器同样可以被for和next调用但是由于没有其他过程,在被调用时只会返回值,不会有其他动作

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

目前评论:1   其中:访客  0   博主  1

    • avatar 吴老二 Admin

      用心写了