我正在编写Zigzag Iterator,它是以下列方式迭代2D列表:
[1,4,7]
[2,5,8,9]
[3,6]
至
[1,2,3,4,5,6,7,8,9]
我实现了一个算法:
class ZigzagIterator:
def __init__(self, vecs):
self.vecs = []
self.turns = 0
for vec in vecs:
vec and self.vecs.append(iter(vec))
def next(self):
try:
elem = self.vecs[self.turns].next()
self.turns = (self.turns+1) % len(self.vecs)
return elem
except StopIteration:
self.vecs.pop(self.turns)
if self.hasNext():
self.turns %= len(self.vecs)
def hasNext(self):
return len(self.vecs) > 0
if __name__ == "__main__":
s = ZigzagIterator([[1,4,7],[2,5,8,9],[3,6]])
while s.hasNext():
print s.next()
>>> 1 2 3 4 5 6 7 8 None None 9 None
我知道问题是因为我再次调用每个列表的next(),然后我得到3无.我可以通过使用java检查hasnext方法来解决此问题.我也可以在python中实现一个hasnext Iterator.我的问题是如何以更加pythonic的方式解决这个问题,而不是用Java思考它.
最佳答案 这是
itertools
docs中的循环配方.
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
num_active = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while num_active:
try:
for next in nexts:
yield next()
except StopIteration:
# Remove the iterator we just exhausted from the cycle.
num_active -= 1
nexts = cycle(islice(nexts, num_active))