我在 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
原文由 vkaul11 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果你不使用你的收益结果,*你 总是 可以把这个:
……进入这个:
可能会有性能成本,**但从来没有语义差异。
不!迭代器和生成器的全部要点是您不需要构建实际列表并将它们附加在一起。
但 效果 是相似的:你只是从一个中屈服,然后从另一个中屈服。
如果您将上半部分和下半部分视为“惰性列表”,那么是的,您可以将其视为创建更大“惰性列表”的“惰性追加”。如果你在父函数的结果上调用
list
,你当然 会 得到一个实际的list
这相当于将两个列表附加在一起,如果你已经完成yield list(…)
而不是yield from …
。但我认为反过来想更容易:它所做的与
for
循环所做的完全相同。如果将两个迭代器保存到变量中,并循环遍历
itertools.chain(upper, lower)
,这与循环第一个然后循环第二个是一样的,对吗?这里没有区别。事实上,您可以将chain
实现为:\* 不是生成器向其调用者产生的值,生成器中 yield 表达式本身的值(来自调用者使用
send
方法),如 PEP 342 中所述。您没有在示例中使用这些。而且我愿意打赌你不在你的真实代码中。但是协程式代码通常使用yield from
表达式的值——参见 PEP 3156 示例。此类代码通常依赖于 Python 3.3 生成器的其他功能——特别是新的StopIteration.value
来自引入yield from
的同一 PEP 380 --- 因此必须重写。但如果没有,您可以使用 PEP 也向您展示完全可怕的混乱等价物,您当然可以削减您不关心的部分。如果您不使用表达式的值,它会减少到上面的两行。\*\* 不是很大,除了使用 Python 3.3 或完全重构代码之外,您无能为力。这与将列表推导式转换为 Python 1.5 循环的情况完全相同,或者在版本 XY 中有新优化而您需要使用旧版本的任何其他情况。