簡體   English   中英

python itertools:使用islice循環

[英]python itertools: Using cycle with islice

題:

我有下面的代碼。 我想知道為什么我是否在下面的代碼中包含注釋行。

#!/usr/bin/env python

from itertools import *
import time
cc = cycle([ iter([1,2,3]), iter([4]) , iter([5,6]) ] )
p = 3
while p:
    try:
        for k in cc:
            print k.next()
    except StopIteration:
        p = p - 1
        cc = cycle(islice(cc,  p))  # this does not matter

輸出:

1
4
5
2
6
3

還要檢查roundrobin食譜

http://docs.python.org/2.7/library/itertools.html

此代碼顯示islice正在影響cc

#!/usr/bin/env python

from itertools import *
import time
cc = cycle([ iter([1,2,3]), iter([4]) , iter([5,6]) ] )
p = 3
while p:
    try:
        for k in cc:
            print k,k.next()
    except StopIteration:
            print "stop iter"
            p = p - 1
            cc = cycle(islice(cc,  p)) 

產量

<listiterator object at 0x7f32bc50cfd0> 1
<listiterator object at 0x7f32bc518050> 4
<listiterator object at 0x7f32bc518090> 5
<listiterator object at 0x7f32bc50cfd0> 2
<listiterator object at 0x7f32bc518050> stop iter
<listiterator object at 0x7f32bc518090> 6
<listiterator object at 0x7f32bc50cfd0> 3
<listiterator object at 0x7f32bc518090> stop iter
<listiterator object at 0x7f32bc50cfd0> stop iter

短期課程:有和沒有重新綁定cc的行為通常不相同,但輸出恰好與您使用的特定輸入相同。

長期課程:讓我們打電話給你的三個迭代器A,B和C.

沒有cc重新綁定:A產生1,B產生4,C產生5,A產生2,B產生StopIteration p下降到2.然后C產生6,A產生3,B 再次引發StopIteration p降至StopIteration引發StopIteration p下降到0,循環退出。

使用cc重新綁定:A產生1,B產生4,C產生5,A產生2,B產生StopIteration p下降到2.到目前為止一切都一樣。 循環算法中重新綁定的目的是刪除耗盡的迭代器。 碰巧在這個具體的例子中,它對結果沒有影響。 使用重新綁定islice(cc, 2)cc獲取“接下來的兩件事”,按順序,C和A. B不再存在。 然后C和A進入一個新的cycle

然后C產生6,A產生3,C產生StopIteration p降到1. cc重新綁定擺脫了C(耗盡的迭代器),在新的cycle只留下了A. 循環StopIteration ,A引發StopIteration p降到0,我們就完成了。

當然,刪除耗盡的迭代器對於使循環正常工作至關重要。 但是,如您所示,有些具體情況無關緊要:-)

簡單的例子

重新綁定cc一個簡單案例有很大的不同:

cc = cycle([iter([1,2,3,4,5]), iter([])])
p = 2

通過重新綁定,我們獲得所有5個值。 沒有重新綁定,我們只得到1和2。

嗯......看起來它正在做這里所期待的事情。

所以,通常,循環的工作方式如下:

cycle([1,2,3,4,5]) -> [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]

它將存儲值,直到它獲得StopIterator,然后它將開始從其保存的列表返回值。 在這種情況下,那將是[iter(a), iter(b), iter(c)] (其中iter(x)是一個listiterator對象本身,跨越任何內部)。 因此,鏈實際上會返回這樣的東西:

[iter(a), iter(b), iter(c), iter(a), iter(b), iter(c), iter(a), iter(b), iter(c), ...]

運行它時看起來像什么:

[1, 4, 5, 2, StopIterator]

但這是k.next()的值,而不是k。 cc本身沒有返回StopIterator,它返回的對象是。

現在,你打電話給islice(cc,2) 這應該返回序列[iter(c), iter(a)] ,因為它們是序列中的下兩個項目。 再一次,你想讓cc循環它們,但現在你應該得到它

[iter(c), iter(a), iter(c), iter(a), iter(c), iter(a), ...]

你不會注意到很多差異,但那是因為你的切片小於原始切片的長度。 換句話說,原件會消失[iter(c),iter(a),iter(b),iter(c),iter(a),...]

但你必須走得比兩個項目更遠才能看到這種差異,並......

你開始拉掉物品就可以了

[6, 3, StopIterator]

只有兩個項目,所以它們是你在沒有islice的情況下得到的兩個項目。

現在,當您執行islice(cc, 2) ,您將獲得接下來的兩個項目[iter(a), iter(c)] 這兩個都用盡了,所以你得到了

[StopIterator]

和你的確切順序。

我不知道你在期待什么,但這完全符合我的預期。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM