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在堆栈上累积)