[英]Python 3 itertools.islice continue despite UnicodeDecodeError
[英]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.