Home > database >  Python 3.10 Generator Expression Exception Handling?
Python 3.10 Generator Expression Exception Handling?

Time:12-06

The code below is from the book "Functional Python Programming, Steven F. Lott" however I can't handle the exception and run the code as expected.

How can I handle the "RuntimeError: generator raised StopIteration"?

Note: I tried googling and read all the results I found from stackoverflow.

Thanks.

from typing import Callable, Iterable, Tuple, Iterator, Any

def group_by_iter(n: int, items: Iterator) -> Iterator[Tuple]:
    """
    .>>> list( group_by_iter( 7, filter( lambda x: x%3==0 or x%5==0, range(1,50) ) ) )
    [(3, 5, 6, 9, 10, 12, 15), (18, 20, 21, 24, 25, 27, 30), (33, 35, 36, 39, 40, 42, 45), (48,)]
    """
    row = tuple(next(items) for i in range(n))
    while row:
        yield row
        row = tuple( next(items) for i in range(n) )

print( list( group_by_iter( 7, filter( lambda x: x%3==0 or x%5==0, range(1,50) ) ) ) )

CodePudding user response:

The built-in next() function can take a second argument which is the default value returned when the iterator is exhausted. You could exploit this functionality to avoid the StopIteration error by returning None by default and filtering it from the result.

Change tuple(next(items) for _ in range(n)) to tuple(e for e in [next(items, None) for _ in range(n)] if e is not None) and the final tuple will be generated cleanly.

from typing import Callable, Iterable, Tuple, Iterator, Any

def group_by_iter(n: int, items: Iterator) -> Iterator[Tuple]:
    """
    .>>> list( group_by_iter( 7, filter( lambda x: x%3==0 or x%5==0, range(1,50) ) ) )
    [(3, 5, 6, 9, 10, 12, 15), (18, 20, 21, 24, 25, 27, 30), (33, 35, 36, 39, 40, 42, 45), (48,)]
    """
    row = tuple(next(items) for _ in range(n))
    while row:
        yield row
        row = tuple(e for e in [next(items, None) for _ in range(n)] if e is not None)

print( list( group_by_iter( 7, filter( lambda x: x%3==0 or x%5==0, range(1,50) ) ) ) )

Output:

[(3, 5, 6, 9, 10, 12, 15), (18, 20, 21, 24, 25, 27, 30), (33, 35, 36, 39, 40, 42, 45), (48,)]
  • Related