`

Python 迭代器和生成器

阅读更多
迭代器
迭代器只不过是一个实现迭代器协议的容器对象。它基于两个方法:
  • next 返回容器的写一个项目;
  • __iter__ 返回迭代器本身。


迭代器可以通过使用一个iter内建函数和一个序列来创建,示例如下。
>>> i = iter('abc')
>>> i.next()
'a'
>>> i.next()
'b'
>>> i.next()
'c'
>>> i.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

引用
当序列遍历完时,将抛出一个StopIteration异常。这将使迭代器与循环兼容,因为它将捕获这个异常以停止循环。要创建定制的迭代器,可以编写一个具有next方法的类,只要该类能够提供返回迭代器实例的__iter__特殊方法。

class MyIterator(object):
    def __init__(self, step):
        self.step = step

    def next(self):
        if self.step == 0:
            raise StopIteration
        self.step -= 1
        return self.step

    def __iter__(self):
        return self

for el in MyIterator(4):
    print el

生成器
引用
生成器提供了一种出色的方法,使得需要返回一系列元素的函数所需的代码更加简单、高效。基于yield指令,可以暂停一个函数并返回中间结果。该函数将保存执行环境并且可以在必要时恢复。

#!/usr/bin/env python
#-*-coding:utf-8-*-

def fibonacci():
    a, b = 0, 1
    while  True:
        yield b
        a, b = b, a + b

fib = fibonacci()
print [fib.next() for i in range(10)]
print map(lambda x,f = lambda x,f:f(x-1,f)+f(x-2,f) if x >1 else x:f(x,f),range(10))


Python引入的与生成器相关的最后一个特性是提供了与next方法调用的代码进行交互的功能。yield将变成一个表达式,而一个值可以通过名为send的新方法来传递,如下所示。
def psychologist():
    print 'Please tell me your problems'
    while True:
        answer = (yield)
        if answer is not None:
            if answer.endswith('?'):
                print ("Don't ask yourself too much questions")
            elif 'good' in answer:
                print "A that's good, go on"
            elif 'bad' in answer:
                print "Don't be so negative"

free = psychologist()
free.next()
free.send('I feel bad')
free.send("?")
free.send("ok then i should find what is good for me")


Output:
Please tell me your problems
Don't be so negative
Don't ask yourself too much questions
A that's good, go on

send的工作机制与next一样,但是yield将变成能够返回传入的值。因而,这个函数可以根据客户端代码来改变其行为。同时,还添加了throw和close两个函数,以完成该行为。它们将向生成器抛出一个错误:
throw 允许客户端代码传入要抛出的任何类型的异常;
close的工作方式是相同的,但是将会抛出一个特定的异常——GeneratorExit,在这种情况下,生成器函数必须再次抛出GeneratorExit或StopIteration异常。
def my_generator():
    try:
        yield 'something'
    except ValueError:
        yield 'dealing with the exception'
    finally:
        print "ok let's clean"

gen = my_generator()
print gen.next()
print gen.throw(ValueError('mean mean mean'))
gen.close()
print gen.next()


finally部分在之前的版本是不允许使用的,它将捕获任何未被捕获的clise和throw调用,是完成清理工作的推荐方式。
协同程序

协同程序是可以挂起、回复,并且有多个进入点的函数。它们可以实现协同的多任务和管道机制。例如:每个协同程序将消费或生产的数据,然后暂停,直到其他数据被传递。
在Python中,协同程序的替代者是线程,它可以实现代码块之前的交互。但是因为它们表现出一种抢先式的风格,所以必须注意资源锁,而协同程序不需要。这样的代码可能变得相当复杂,难以创建和调试。但是生成器几乎就是协同程序,添加send、throw和close其初始的意图就是为该语言提供一种类似协同程序的特性。

使用multimask模块
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import multitask

def coroutine_1():
    for i in range(3):
        print 'c1'
        yield i 

def coroutine_2():
    for i in range(3):
        print 'c2'
        yield i

multitask.add(coroutine_1())
multitask.add(coroutine_2())
multitask.run()

在协同程序之间的写作,最经典的例子是接受来自多个客户的查询,并将每个查询委托给对此作出相应的新线程的服务器应用程序。
#!/usr/bin/env python
# -*- coding:utf-8 -*-

from __future__ import with_statement
from contextlib import closing
import socket
import multitask

def client_handler(sock):
    while closing(sock):
        while True:
            data = (yield multitask.recv(sock, 1024))
            if not data:
                break
            yield multitask.send(sock, data)

def echo_server(hostname, port):
    addrinfo = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC,socket.SOCK_STREAM)
    (family, socktype, proto, cannoname, sockaddr) = addrinfo[0]
    with closing(socket.socket(family,socktype,proto)) as sock:
        sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        sock.bind(sockaddr)
        sock.listen(5)
        while True:
            multitask.add(client_handler((yield multitask.accept(sock))[0]))

if __name__ == "__main__":
    import sys
    hostname = None
    port = 1111
    if len(sys.argv) > 1:
        hostname = sys.argv[1]
    if len(sys.argv) > 2:
        port = int(sys.argv[2])
    multitask.add(echo_server(hostname,port))
    try:
        multitask.run()
    except KeyboardInterrupt:
        pass


生成器表达式
>>> iter = (x**2 for x in range(10) if x % 2 == 0)
>>> for el in iter:
... print el
… 
0
4
16
36
64

itertools模块
islice:窗口迭代器
tee:往返式的迭代器
groupby:uniq迭代器
#!/usr/bin/env python
#-*-coding:utf-8-*-

from itertools import group by
def compress(data):
    return ((len(list(group)),name) for name,group in groupby(data))

def decompress(data):
    return (car * size for size, car in data)

print list(compress('get uuuuuuuuuuuuuuuup'))
compressed = compress('get uuuuuuuuuuuuuuuup')
print ''.join(decompress(compressed))



以上内容整理于PYTHON高级编程
分享到:
评论

相关推荐

    快速学习-Python迭代器和生成器

    14.1 迭代器生成 字符串,列表或元组对象都可用于创建迭代器 list=[1,2,3,4] it = iter(list) # 创建迭代器对象 print(next(it)) # 输出迭代器的下一个元素 print(next(it)) 14.2 迭代器遍历 list=[1,2,3,4] it =...

    python 迭代器与生成器-9.两个变量间的逻辑运算-是非,对错?.py

    从这部分内容中,我们可以提取出关于Python迭代器和生成器的核心知识点: - 迭代器是一个遵循迭代器协议的对象,实现有`__iter__()`和`__next__()`方法。 - 生成器是一种特殊的迭代器,用`yield`来提供值,适合处理...

    老男孩python-27-python迭代器和生成器.mp4

    Python运维教程

    python生成器和迭代器区别

    总的来说,生成器和迭代器是Python中实现迭代的关键工具,它们提供了优雅地处理序列数据的方式,尤其是处理大型数据集时,可以避免一次性加载全部数据导致的内存问题。熟练掌握这两者的使用,能极大地提高Python编程...

    python 迭代器与生成器介绍与示例.zip

    在Python编程语言中,迭代器和生成器是两个核心概念,它们对于处理集合数据和实现高效算法起着至关重要的作用。迭代器是Python中的一个对象,它实现了迭代器协议,即包含`__iter__()`和`__next__()`方法。迭代器协议...

    python迭代器与生成器示例代码之自定义迭代器遍历数字序列

    在Python中,迭代器和生成器是进行数据处理和产生数据序列的两种常用方式。迭代器是一种对象,它可以记住遍历的位置,从而每次调用next()方法时返回序列中的下一个值。生成器是创建迭代器的一种更简单的方式,它允许...

    Python迭代器和生成器定义与用法示例

    本文实例讲述了Python迭代器和生成器定义与用法。分享给大家供大家参考,具体如下: 迭代器 iter() 迭代器是访问集合中元素的一种方式,迭代器 object 从集合中的第一个元素开始访问,直到所有的元素被访问完成. 所以...

    彻底搞懂python 迭代器和生成器

    ### 彻底理解Python迭代器和生成器 #### 一、引言 在Python编程语言中,迭代器和生成器是非常重要的概念,它们为高效处理大量数据提供了强大的工具。本文将深入探讨Python中的迭代器和生成器的概念、原理及其应用...

    「Python系列」Python迭代器与生成器.md

    「Python系列」Python迭代器与生成器

    Python 中迭代器与生成器详解及其应用实例

    内容概要:本文详细介绍了 Python 中的迭代器和生成器的概念、创建方法及其应用场景。首先解释了迭代器的基本概念、创建方法以及应用场景,如处理大型数据集和实现自定义遍历逻辑。接着介绍了生成器的概念,展示了...

    Python语言基础:迭代器和生成器.pptx

    迭代器和生成器是Python编程中的重要概念,特别是在处理大量数据或进行高效内存管理时,它们的优势尤为明显。本文将详细讲解这两个概念及其在Python语言中的应用。 **迭代器** 迭代器是Python中访问集合元素的一种...

    python 协程中的迭代器,生成器原理及应用实例详解

    本文实例讲述了python 协程中的迭代器,生成器原理及应用。分享给大家供大家参考,具体如下: 1.迭代器理解 迭代器: 迭代器是访问可迭代对象的工具 迭代器是指用iter(obj)函数返回的对象(实例) 迭代器是指用next(it...

    Python中的迭代器与生成器:深入理解与应用

    Python是一种支持多种迭代模式的高级编程语言,其中迭代器(Iterator)和生成器(Generator)是两种非常重要的迭代机制。它们在处理数据集合时提供了不同的方法和优势。本文将深入探讨Python中的迭代器和生成器,...

    python迭代器与生成器示例代码之文件行迭代器

    Python中的迭代器和生成器是两种不同的概念,它们都能使你遍历一个序列,但处理方式各有特色。迭代器是一个实现了迭代器协议的对象,即实现了__iter__()和__next__()方法的对象。生成器是一种特殊的迭代器,它允许在...

    Python-100-Days-python 迭代器与生成器

    在Python编程语言中,迭代器(Iterators)和生成器(Generators)是两种不同的概念,它们都与数据的遍历处理有着密切的关系。迭代器是一种遵循迭代器协议的对象,它可以记住遍历的位置,从而允许在多个循环中进行...

    python 迭代器与生成器-7.打印学生平均成绩-emm~.py

    在Python编程语言中,迭代器和生成器是两个重要概念,它们为处理集合数据提供了一种高效的方式。迭代器是一种特殊的对象,它允许我们顺序访问集合中的每一个成员,而不必暴露集合的内部结构。生成器是一种使用了特殊...

    通过python实现迭代器与生成器.rar

    在Python中,迭代器和生成器是两个用于处理序列数据的重要概念。它们允许你以高效且节省内存的方式处理大量数据。以下是它们的基本概念和用法。 迭代器(Iterator) 迭代器是一个对象,它实现了两个方法:__iter__()...

    深入讲解Python中的迭代器和生成器

    ### 深入讲解Python中的迭代器和生成器 #### 一、迭代器的基本概念 在Python编程语言中,迭代器是一种遵循特定协议的对象,它允许我们遍历一系列数据项。这种遍历方式广泛应用于各种数据结构,如列表(list)、...

    python 迭代器与生成器-2.判断是否在列表中-千方百计只为在你心里.py

    Python中的迭代器和生成器是两种不同的概念,但它们都与数据处理和循环遍历紧密相关。迭代器是一个实现了迭代器协议的对象,该协议包含了`__iter__()`和`__next__()`两个方法。`__iter__()`方法返回迭代器对象本身,...

Global site tag (gtag.js) - Google Analytics