首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python迭代工具:对孤岛使用周期

python迭代工具:对孤岛使用周期
EN

Stack Overflow用户
提问于 2013-10-02 18:40:02
回答 2查看 1.2K关注 0票数 4

问题:

下面有密码。我想知道为什么我在下面的代码中包括了注释行并不重要。

代码语言:javascript
复制
#!/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

输出:

代码语言:javascript
复制
1
4
5
2
6
3

还请查看roundrobin菜谱

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

此代码显示islice正在影响cc

代码语言:javascript
复制
#!/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)) 

输出

代码语言:javascript
复制
<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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-02 20:11:49

好吧..。看上去它在做这里所期望的事情。

所以,通常情况下,循环是这样工作的:

代码语言:javascript
复制
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对象,跨越内部的任何内容)。因此,chain实际上是返回了这样的东西:

代码语言:javascript
复制
[iter(a), iter(b), iter(c), iter(a), iter(b), iter(c), iter(a), iter(b), iter(c), ...]

当你运行它时看起来是什么样子的:

代码语言:javascript
复制
[1, 4, 5, 2, StopIterator]

但这是k.next()的值,而不是K。抄送本身不返回StopIterator,它返回的对象是。

现在,你打电话给islice(cc,2)。这将返回序列[iter(c), iter(a)],因为这是序列中的下两个项。同样,您希望cc循环它们,但是现在您应该

代码语言:javascript
复制
[iter(c), iter(a), iter(c), iter(a), iter(c), iter(a), ...]

您不会注意到有什么不同,但这是因为您的切片小于原始的长度。换句话说,原来的iter(c)、iter(a)、iter(b)、iter(c)、iter(a)、.

但你必须走得更远才能看到这种差别,而且.

你开始把东西取下来,你就得到

代码语言:javascript
复制
[6, 3, StopIterator]

只有两个项目,所以他们是相同的两个项目,你会得到没有岛。

现在,当您执行islice(cc, 2)时,您将得到下两个项,即[iter(a), iter(c)]。这两个都累坏了,所以你

代码语言:javascript
复制
[StopIterator]

以及你的确切顺序。

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

票数 4
EN

Stack Overflow用户

发布于 2013-10-02 20:19:51

短期内:有和没有重新绑定cc的行为通常不是,通常是相同的,但是对于您使用的特定输入,输出发生是相同的。

长程:让我们调用您的三个迭代器A、B和C。

如果没有cc重新绑定:a产生1,B产生4,C产生5,A产生2,B引发StopIterationp降至2,C生成6,A生成3,B再次引起StopIterationp降至1.C,StopIteration升高。p下降到0,循环退出。

使用cc重新绑定:a产生1,B产生4,C产生5,A产生2,B引发StopIterationp下降到2,到目前为止都是如此。在循环算法中重新绑定的目的是删除耗尽的迭代器.在这个具体的例子中,它对结果没有任何影响。通过重新绑定,islice(cc, 2)cc获得了“接下来的两件事”,按照顺序,C和A.B不再存在。然后将C和A放入一个新的cycle中。

然后C生成6,A生成3,C生成StopIterationp降到1,cc重新绑定可以摆脱C(耗尽的迭代器),只留下一个新的cycle中的A。循环会转一圈,然后A会引发StopIterationp降到0,我们就完了。

当然,清除耗尽的迭代器是使循环正常工作的关键。但是,正如您所展示的,在某些特定的情况下,这并不重要:)

简单例子

在一个简单的案例中,重新绑定cc产生了巨大的差异:

代码语言:javascript
复制
cc = cycle([iter([1,2,3,4,5]), iter([])])
p = 2

通过重新绑定,我们得到了所有的5个值。没有重新绑定,我们只能得到1和2。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19144320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档