Nick W
Nick W

Reputation: 59

How to create a Generator keeps going after StopIteration?

If I have multiple iterables as argument, and is there any way to keep the code going after one of the list raise StopIteration?

I cannot use any slicing, len(), or any itertools.

This is what I have tried so far, and I know it is totally wrong but I just cannot figure this out.

def together(*args):
    iterator = [iter(item) for item in args]
    my_list = []

    while True:
            for i in iterator:
                try:
                    lst.append(next(i))
                    print(next(i))
                except StopIteration:
                    return
            if '__next__' == None:
                yield tuple(None)
            else:
                yield tuple(my_list)
            my_list = []

Here is my current result, iter do store b,g,i but it only prints out first list:

[('a', 'f', 'h')]

Whats the best way to get a result like this? Resutls are tuples in a list, and when argument iterables runs out then it get replaced with Nones.

[('a', 'f', 'h'), ('b', 'g', 'i'), ('c', None, 'j'), ('d', None, 'k'), ('e', None, None)]

I know the StopIteration error rises after the ('b','g','i'), but is there any way to ignore and keep going with different list?

And input looks like:

[v for v in together(disguise('abcde'), disguise('fg'), disguise('hijk'))]

disguise function looks like:

def disguise(items):
    for v in items:
        yield v

Any suggestion or help will be appreciated!

Upvotes: 2

Views: 169

Answers (1)

blhsing
blhsing

Reputation: 106533

You can use the second parameter of next to let next return a default value instead of raising a StopIteration exception when a given iterator is exhausted:

def together(*seqs):
    seqs = list(map(iter, seqs))
    while True:
        group = tuple(next(seq, None) for seq in seqs)
        if all(i is None for i in group):
            return
        yield group

so that:

list(together('abcde', 'fg', 'hijk'))

returns:

[('a', 'f', 'h'), ('b', 'g', 'i'), ('c', None, 'j'), ('d', None, 'k'), ('e', None, None)]

Upvotes: 3

Related Questions