python迭代器和生成器

简介:

列表推导:

生成一个列表:[0,2,4,6,8]

>>> [i for i in range(10) if i % 2 == 0]
[0,2,4,6,8]

 

enumerate

seq = ["one","two","three"]
for i,element in enumerate(seq):
    seq[i] = '%d:%s' % (i,seq[i])

 

上面的代码将生成下面的列表: ['0:one','1:two','2:three']

迭代器:

复制代码
>>> 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 异常

生成器

复制代码
>>> def fibonacci():
...     a, b = 0, 1
...     while True:
...         yield b
...         a, b = b, a+b
... 
>>> fib = fibonacci()
>>> fib.next()
1
>>> fib.next()
1
>>> fib.next()
2
>>> [fib.next() for i in range(10)]
[3, 5, 8, 13, 21, 34, 55, 89, 144, 233]
>>>
复制代码

 

协同程序

协同不同于多线程,线程是抢占式的,下面的例子可以说明这点:

复制代码
#!/usr/bin/env python
#coding=utf-8
#协同
import multitask
from threading import Thread
import time

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

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

def conroutine_3():
    for i in range(3):
        print 'c3'

def conroutine_4():
    for i in range(3):
        print 'c4'

print "==========协同========"
multitask.add(conroutine_1())
multitask.add(conroutine_2())
multitask.run()

print "==========多线程========"
a = Thread(target=conroutine_3,args=())
b = Thread(target=conroutine_4,args=())
a.start()
b.start()
复制代码

 

上面的程序运行的结果可能是这样的:

复制代码
==========协同========
c1
c2
c1
c2
c1
c2
==========多线程========
c3
c3c4

c3
c4
c4
复制代码

 

从结果来看,协同程序c1和c2依次执行,多线程的执行结果就不好说了,有多种可能

下面的程序是用生成器形成的echo服务器

复制代码
#!/usr/bin/env python
#coding=utf-8
from __future__ import with_statement
from contextlib import closing
import socket
import multitask
def client_handler(sock):
    with closing(socket):
        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, canonname,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__':
    hostname = 'localhost'
    port = 1111
    multitask.add(echo_server(hostname,port))
    try:
        multitask.run()
    except KeyboardInterrupt:
        pass
复制代码

 

上面的代码理解起来有点难度,我也有些地方不太懂,测试的话可以用telnet,方法是:

telnet localhost 1111

 

然后再输入一些信息,回车以后会显示你发送的信息。

itertools模块

islice:窗口迭代器
复制代码
#!/usr/bin/env python
#coding=utf-8
import itertools
def starting_at_five():
    value = raw_input("input1").strip()
    while value != '':
        for el in itertools.islice(value.split(),4,None):
            yield el
        value = raw_input("input2").strip()

iter = starting_at_five()
while True:
    print iter.next()
复制代码

 

下面是一些测试输入输出:

复制代码
input1: 1 2 3 4 5 6
5
6
input2: 1 2    
input2: 1 2 3 4 5 6 7 8
5
6
7
8
input2: 
复制代码

 

从上面的例子可以看出,上面的代码是输出第4个之后的元素,利用这个功能我们可以输出特定位置的元素

tee
复制代码
#!/usr/bin/env python
#coding=utf-8
import itertools
def with_head(iterable,headsize=1):
    a, b = itertools.tee(iterable)
    print list(itertools.islice(a,headsize)),b
seq = [1]
with_head(seq)
seq = [1,2,3,4]
with_head(seq,4)
复制代码

 


上面的代码我也没看懂,具体怎么用还需要进一步学习

代码运行结果是:

[1] <itertools.tee object at 0xb71f866c>
[1, 2, 3, 4] <itertools.tee object at 0xb71f862c>

 

uniq迭代器:

使用行程长度编码来压缩数据:将字符串中每组相邻的重复字符替换成字符本身的重复字数,没重复则为1,代码实现:

复制代码
#!/usr/bin/env python
#coding=utf-8
import itertools
def compress(data):
    return ((len(list(group)),name) 
            for name,group in itertools.groupby(data))

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

print list(compress('aaasdffffffffffffffffffffff'))
compressed = list(compress('aaasdffffffffffffffffffffff'))
print "".join(decompress(compressed))
复制代码

 

运行结果:

[(3, 'a'), (1, 's'), (1, 'd'), (22, 'f')]
aaasdffffffffffffffffffffff

 


本文转自ma6174博客园博客,原文链接:http://www.cnblogs.com/ma6174/archive/2013/01/06/2847563.html,如需转载请自行联系原作者

相关文章
|
27天前
|
大数据 数据处理 开发者
Python中的迭代器和生成器:不仅仅是语法糖####
本文探讨了Python中迭代器和生成器的深层价值,它们不仅简化代码、提升性能,还促进了函数式编程风格。通过具体示例,揭示了这些工具在处理大数据、惰性求值及资源管理等方面的优势。 ####
|
2月前
|
存储 索引 Python
|
1月前
|
JavaScript 前端开发 算法
python中的列表生成式和生成器
欢迎来到瑞雨溪的博客,这里是一位热爱JavaScript和Vue的大一学生的天地。通过自学前端技术2年半,现正向全栈开发迈进。如果你从我的文章中受益,欢迎关注,我将持续更新高质量内容,你的支持是我前进的动力!🎉🎉🎉
24 0
|
2月前
|
Python
Python生成器、装饰器、异常
【10月更文挑战第15天】
|
2月前
|
传感器 大数据 数据处理
深入理解Python中的生成器:用法及应用场景
【10月更文挑战第7天】深入理解Python中的生成器:用法及应用场景
88 1
|
2月前
|
存储 数据处理 Python
深入解析Python中的生成器:效率与性能的双重提升
生成器不仅是Python中的一个高级特性,它们是构建高效、内存友好型应用程序的基石。本文将深入探讨生成器的内部机制,揭示它们如何通过惰性计算和迭代器协议提高数据处理的效率。
|
1月前
|
存储 程序员 数据处理
深入理解Python中的生成器与迭代器###
本文将探讨Python中生成器与迭代器的核心概念,通过对比分析二者的异同,结合具体代码示例,揭示它们在提高程序效率、优化内存使用方面的独特优势。生成器作为迭代器的一种特殊形式,其惰性求值的特性使其在处理大数据流时表现尤为出色。掌握生成器与迭代器的灵活运用,对于提升Python编程技能及解决复杂问题具有重要意义。 ###
|
2月前
|
存储 索引 Python
Python 迭代器是怎么实现的?
Python 迭代器是怎么实现的?
47 6
|
3月前
|
索引 Python
解密 Python 迭代器的实现原理
解密 Python 迭代器的实现原理
53 13
|
2月前
|
存储 大数据 数据处理
Python 中的列表推导式与生成器:特性、用途与区别
Python 中的列表推导式与生成器:特性、用途与区别
34 2