python系列之 - 迭代器、生成器

来源:互联网 发布:linux配置ntp同步 编辑:程序博客网 时间:2024/05/21 17:35

1 迭代器 (iterator)

迭代器是访问集合元素的一种方式,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。

迭代器的好处是,迭代器在返回数据的时候是每次返回集合中的一个元素,而不是一次将所有的元素全部提取到内存中,这样节约内存。特别是在提取比较大的文件时,更能体现迭代器的优势。

迭代器仅是一容器对象,它实现了迭代器协议。它有两个基本方法:
1)next方法
返回容器的下一个元素
2)__iter__方法
返回迭代器自身


迭代器可使用内建的iter方法创建,见例子:

>>> i = iter('abc')>>> i.next()'a'>>> i.next()'b'>>> i.next()'c'>>> i.next()Traceback (most recent call last):  File "<string>", line 1, in <string>StopIteration:
获取迭代器元素是,可以调用内置的next方法获取,但python处理迭代器越界会抛出StopIteration异常。也可以使用for循环来获取迭代器元素,在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作上面说的都是python自带的容器对象,它们都实现了相应的迭代器方法,那如果是自定义类需要遍历怎么办。这里要用到下面的功能生成器

a = iter(['1','2','3','4'])print(a.value)for i in range(4):    print(a.__next__())


2.生成器 generator

我们在传统的定义函数时,返回值都是使用return,这样对于要返回一个集合都是将集合全部生成完成后一次返回。如果我们要实现一个迭代器时,就要通过yield返回,这样就实现了一个生成器,看下面的例子:

def get_money(account):    while account > 0:        account -= 100        yield 100        print("取出100块")a2 = get_money(500)print(a2.__next__())print('came back again!')print(a2.__next__())结果:第一次: 100came back again!取出100块第二次 100

从上面例子看出,当使用yield返回结果时,不是一次将最后的结果全部返回,而是先返回一个值,当再次调用next方法取值时,将接着上一次返回结果的地方接着运行。

我们使用yield不仅可以从函数的循环中一次一个的返回值,也可以在循环的过程中接收外界的值,这个是非常cool的。看下面的例子:

def consumer(name):    while True:        in_com = yield        print("%s get the value %s" % (name,in_com))def producers():    a1 = consumer('A')    a2 = consumer('B')    a1.__next__()    a2.__next__()    while True:        for i in range(5):            a1.send(str(i))            a2.send(str(i))        breakproducers()结果:A get the value 0B get the value 0A get the value 1B get the value 1A get the value 2B get the value 2A get the value 3B get the value 3A get the value 4B get the value 4
以上代码其实实现了一个同步的执行异步效果。

文件读取的迭代实现

我们知道使用open读取文件时,有read方法读取全部内容,如果文件大小是G级别的,这将非常消耗内存,我们可以使用下面的方法读取文件:

with open('files.txt','r') as f:    for line in f:        print(line)
这样可以采用迭代的方式每次从文件中读取一行,节省内存


0 0
原创粉丝点击