Python 返回大数据的函数需要惰性求值
现在真的很想念哈斯克尔 我有以下代码:Python 返回大数据的函数需要惰性求值,python,lazy-evaluation,Python,Lazy Evaluation,现在真的很想念哈斯克尔 我有以下代码: for i in someFunc(arg0...argN): //some logic 问题是someFunc的返回值太大,内存不足 我想我可以把它封装在一个生成器中,但这没有帮助,因为我不控制someFunc,也就是做: def gen_someFunc(someFunc): for i in someFunc(arg0...argN): yield i 没有帮助,因为仍然会立即计算someFunc。如何才能懒洋洋地
for i in someFunc(arg0...argN):
//some logic
问题是someFunc
的返回值太大,内存不足
我想我可以把它封装在一个生成器中,但这没有帮助,因为我不控制someFunc
,也就是做:
def gen_someFunc(someFunc):
for i in someFunc(arg0...argN):
yield i
没有帮助,因为仍然会立即计算someFunc
。如何才能懒洋洋地计算someFunc
?在Python(或Haskell,这不是)中,不能懒洋洋地对返回完全物化对象的函数排队。在使用该函数后,可能会发生懒惰,但如果数据一次全部转储到您身上,您对此无能为力
也许有一些参数可以调用你还不知道的函数,这会让你懒散地对它求值,但是我们从这里给出的信息中不知道
如果您可以在内存中保留对数据的初始调用,那么作为生成器调用它的python方法是
gen_some_func = iter(someFunc(arg0...argN))
不要编写此函数,然后稍后再调用它
def gen_someFunc(someFunc):
for i in someFunc(arg0...argN):
yield i
澄清一下,问题是
someFunc
返回的物化数据集太大?这个问题没有通用的解决方案。您需要更改someFunc
,替换它,或以其他方式调用它。@Edgar:Haskell也不会救您。如果一个函数决定返回ByteString
而不是Lazy.ByteString
,那么您同样会迷失方向。不能更改现有代码的行为。懒惰有时会付出巨大的代价。@EdgarAroutiounian:Niklas的观点是,这里的“错误”不在于Python(或任何任意的非Haskell语言);这取决于编写非惰性函数的人。@Edgar:Haskell中的列表相当于Python中的生成器。因此,让我们假设函数将返回一个“大型”生成器,您也不会遇到Python中的问题。没有人会从Haskell函数返回未赋值的“海量列表”,这是导致堆栈溢出的非常可靠的方法(由于未赋值的thunks在堆栈上累积)