python迭代器和產生器

來源:互聯網
上載者:User
文章目錄
  • 列表推導:
  • enumerate
  • 迭代器:
  • 產生器
  • 協同程式
  • itertools模組
列表推導:

產生一個列表:[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 multitaskfrom threading import Threadimport timedef conroutine_1():    for i in range(3):        print 'c1'        yield idef conroutine_2():    for i in range(3):        print 'c2'        yield idef 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()

 

上面的程式啟動並執行結果可能是這樣的:

==========協同========c1c2c1c2c1c2==========多線程========c3c3c4c3c4c4

 

從結果來看,協同程式c1和c2依次執行,多線程的執行結果就不好說了,有多種可能

下面的程式是用產生器形成的echo伺服器

#!/usr/bin/env python#coding=utf-8from __future__ import with_statementfrom contextlib import closingimport socketimport multitaskdef 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-8import itertoolsdef 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 656input2: 1 2    input2: 1 2 3 4 5 6 7 85678input2: 

 

從上面的例子可以看出,上面的代碼是輸出第4個之後的元素,利用這個功能我們可以輸出特定位置的元素

tee
#!/usr/bin/env python#coding=utf-8import itertoolsdef with_head(iterable,headsize=1):    a, b = itertools.tee(iterable)    print list(itertools.islice(a,headsize)),bseq = [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-8import itertoolsdef 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

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.