Python exit consumer on first StopIteration

自作多情 提交于 2019-12-13 04:43:21

问题


It's a follow-up to my 1 generator -- multiple consumers question. As StopIteration is the way the generator signals its exhaustion, unfortunately, I now have many exception-handling code littered all over the place in the client code (for every next() statement in the example below).

Is there a better way to exit with whatever value is built in meal upon hitting the first StopIteration exception?

def client(course, take):
    meal = []
    for _ in range(take):
        try:
            some_meal = next(course)
            meal.append(some_meal)
        except StopIteration:
            pass
    if take % 2 == 0:
        try:
            some_meal = next(course)
            meal.append(some_meal)
        except StopIteration:
            pass
    return meal

UPDATE Eventually, I ended up using 'itertools.islice' (see accepted solution below) as this function takes care of the StopIteration itself (see the for-loop equivalent implementation shown in the itertools doc. I prefer this solution over using next default second argument as it would imply checking each meal (still, I'd better use the latter than all the exception handling above).


回答1:


Just return directly in the first exception handler:

def client(course, take):
    meal = []
    for _ in range(take):
        try:
            some_meal = next(course)
            meal.append(some_meal)
        except StopIteration:
            return meal
    if take % 2 == 0:
        try:
            some_meal = next(course)
            meal.append(some_meal)
        except StopIteration:
            pass
    return meal

although I'd still use the standard library more here and not have to catch those StopIteration exceptions nearly as much:

from itertools import islice


def client(course, take):
    meal = list(islice(course, take))

    if take % 2 == 0:
        some_meal = next(course, None)
        if some_meal is not None:
            meal.append(some_meal)

    return meal



回答2:


Besides using islice, if I read the code correctly then it can be made even simpler:

def client(course, take):
    if take % 2 == 0:
        take += 1
    return list(itertools.islice(course, take))


来源:https://stackoverflow.com/questions/22152578/python-exit-consumer-on-first-stopiteration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!