首页 > 解决方案 > 生成器函数产生最大的可迭代值

问题描述

我是python的初学者,我目前正在为我的班级准备一个测试。在一个问题上,我对某一部分感到困惑。

我们被要求创建一个生成器函数,该函数仅在所有其他可迭代参数停止迭代后产生来自最大可迭代参数的结果。

所以,我的功能目前看起来像这样:

def generator(*args):
    args = [iter(a) for a in args]
    while True:
        yielded = False
        for a in args:
            try:
                yield next(a)
                yielded = True
            except StopIteration:
                pass
        if not yielded:
            return
a = generator('abc', 'abcdef', [1,2])
print([i for i in a])

>>> ['a', 'a', 1, 'b', 'b', 2, 'c', 'c', 'd', 'e', 'f']

但是我想要的是自从参数以来'abcdef',当所有其他参数停止迭代时它不会停止迭代,对吗?我只想打印['d','e','f']

因此,所需的结构应该是:

def generator(*args):
    blah blah

a = generator('abc', 'abcdef', [1,2])
print([i for i in a])

>>>['d','e','f']

我的功能有什么问题吗?

标签: pythongenerator

解决方案


如果您定义一些辅助函数,任务会更容易

vals = ['abc', 'abcdef', [1, 2]]


def next_or_none(iterator):
    """Return the next item in the iterator, or None if the iterator is done.
    """
    try:
        return next(iterator)
    except StopIteration:
        return None


def myzip(*args):
    """Yield one element from each arg, yield None for arg that are done.
    """
    args = [iter(a) for a in args]
    while True:
        res = [next_or_none(a) for a in args]
        if all(v is None for v in res):  # make sure we stop when all iterators are exhausted
            return
        yield res

有了这些定义,您需要做的就是遍历 myzip 生成器,直到它每次迭代只提供一个值。

def remainder(*args):
    for nextarg in myzip(*args):
        notnones = [v for v in nextarg if v is not None]
        if len(notnones) == 1:
            # wait for all but one iterator to be done before yielding.
            yield notnones[0]

print(list(remainder(*vals)))

推荐阅读