【问题标题】:Generator function yield the largest iterable value生成器函数产生最大的可迭代值
【发布时间】:2020-12-02 20:26:42
【问题描述】:

我是 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']

我的功能有什么问题吗?

【问题讨论】:

    标签: python generator


    【解决方案1】:

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

    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)))
    

    【讨论】:

    • 注意,这不适用于所有包含 None 的列表(要解决此问题,您可以使 myzip 仅返回非无值)。
    【解决方案2】:

    试试这个:

    在此代码中,仅对最大参数执行迭代,并且仅从其较大的位置开始。

    def generator(*args):                                     
        sorts = sorted(args, key=len, reverse=True)           
        choose = sorts[0][len(sorts[0])-len(sorts[1]):]       
        gen = iter(choose)                                    
        while True:                                           
            yielded = False                                   
            try:                                              
                yield next(gen)                               
                yielded = True                                
            except StopIteration:                             
                pass                                          
            if not yielded:                                   
                return                                        
    a = generator('abc', 'abcdef', [1,2])                     
    print([i for i in a])                      
               
    

    【讨论】:

    • 您可以将最后一部分简化为for item in choose: yield item
    • ps:你应该用文字和代码来解释你使用的策略(因为只有代码的答案是不受欢迎的......)
    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2016-01-30
    • 2018-05-16
    • 1970-01-01
    • 2016-01-09
    相关资源
    最近更新 更多