Zigzag Iterator的Pythonic方式?

我正在编写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))
点赞