将“ yield from”语句转换为Python 2.7代码

我在下面的Python 3.2中有一个代码,我想在Python 2.7中运行它。我确实进行了转换(已经missing_elements在两个版本中都放了代码),但是我不确定这是否是最有效的方法。基本上,如果函数的yield from上半部和下半部有两个类似下面的调用,会发生什么情况missing_element?是否将两个半部分(上半部分和下半部分)中的条目彼此追加到一个列表中,以便父递归函数与yield from调用一起使用并将这两个半部分一起使用?


def missing_elements(L, start, end):  # Python 3.2

    if end - start <= 1: 

        if L[end] - L[start] > 1:

            yield from range(L[start] + 1, L[end])

        return


index = start + (end - start) // 2


# is the lower half consecutive?

consecutive_low =  L[index] == L[start] + (index - start)

if not consecutive_low:

    yield from missing_elements(L, start, index)


# is the upper part consecutive?

consecutive_high =  L[index] == L[end] - (end - index)

if not consecutive_high:

    yield from missing_elements(L, index, end)


def main():

    L = [10, 11, 13, 14, 15, 16, 17, 18, 20]

    print(list(missing_elements(L, 0, len(L)-1)))

    L = range(10, 21)

    print(list(missing_elements(L, 0, len(L)-1)))


def missing_elements(L, start, end):  # Python 2.7

    return_list = []                

    if end - start <= 1: 

        if L[end] - L[start] > 1:

            return range(L[start] + 1, L[end])


    index = start + (end - start) // 2


    # is the lower half consecutive?

    consecutive_low =  L[index] == L[start] + (index - start)

    if not consecutive_low:

        return_list.append(missing_elements(L, start, index))


    # is the upper part consecutive?

    consecutive_high =  L[index] == L[end] - (end - index)

    if not consecutive_high:

        return_list.append(missing_elements(L, index, end))

    return return_list


繁星coding
浏览 756回答 3
3回答

蓝山帝景

如果您不使用收益率*,则可以随时将其转换为:yield from foo…变成这样:for bar in foo:&nbsp; &nbsp; yield bar可能会有性能成本**,但从语义上讲永远不会有差异。是否将两个半部分(上半部分和下半部分)中的条目彼此追加到一个列表中,以使父递归函数与call的收益并同时使用这两个半部分?没有!迭代器和生成器的全部要点是,您无需构建实际的列表并将它们附加在一起。但是效果是相似的:您只是从一种收益,然后从另一种收益。如果您将上半部分和下半部分视为“懒惰列表”,则可以,您可以将其视为“懒惰附加”,它会创建一个较大的“懒惰列表”。而且,如果您调用list父函数的结果,那么您当然会得到一个实际值list,该值等于将如果执行yield list(…)而不是所获得的两个列表加在一起yield from …。但是我认为反过来更容易想到:它的作用与for循环完全相同。如果将两个迭代器保存到变量中并进行循环itertools.chain(upper, lower),则与在第一个循环然后在第二个循环上进行相同,对吗?没什么区别。实际上,您可以实现chain如下:for arg in *args:&nbsp; &nbsp; yield from arg*不是生成器产生给调用者的值,而是生成器内部的yield表达式本身的值(使用send方法从调用者产生),如PEP 342中所述。您没有在示例中使用这些。而且我敢打赌您不在您的真实代码中。但是协程式代码通常使用yield from表达式的值- 有关示例,请参阅PEP 3156。此类代码通常取决于Python 3.3生成器的其他功能-特别是StopIteration.value来自引入了同一PEP 380的新功能yield from-因此必须将其重写。但是,如果没有,您可以使用PEP来向您显示完整的,混乱的等价物,当然您也可以减少不需要的部分。而且,如果您不使用表达式的值,它将缩减为上面的两行。**数量不多,除了使用Python 3.3或完全重组代码外,您无能为力。这与将列表解析转换为Python 1.5循环完全相同,或者在XY版本中进行了新的优化并且您需要使用旧版本时,则与其他情况完全相同。

繁星淼淼

我只是碰到这个问题,我使用的是一个有点困难,因为我需要返回值的yield from:result = yield from other_gen()不能将其表示为简单的for循环,但可以用以下方式重现:_iter = iter(other_gen())try:&nbsp; &nbsp; while True: #broken by StopIteration&nbsp; &nbsp; &nbsp; &nbsp; yield next(_iter)except StopIteration as e:&nbsp; &nbsp; if e.args:&nbsp; &nbsp; &nbsp; &nbsp; result = e.args[0]&nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; result = None希望这将帮助遇到相同问题的人们。:)

慕田峪9158850

用for循环替换它们:yield from range(L[start] + 1, L[end])==>for i in range(L[start] + 1, L[end]):&nbsp; &nbsp; yield i关于元素也是如此:yield from missing_elements(L, index, end)==>for el in missing_elements(L, index, end):
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python