懒惰评估地图

懒惰评估地图,第1张

懒惰评估地图

您在这里比较苹果和桔子。

range
不是
只是一个懒惰的迭代。它是一个特定的对象,其内容满足特定的法律,该法律允许支持许多 *** 作而无需在内存中实际构建巨大的序列。这是因为的第n个元素
range
基本上只是
start+ n*step
(模
stop
,符号等)

但是

map
意味着 可以使用 任何 功能
f
。特别是功能可能具有共享/全局状态,这已经失去了在
map(f,something)[100]
不执行100个功能调用的情况下能够执行的任何机会。不这样做会破坏结果的 正确性

map
“懒惰”只是意味着它不会立即生成完整的结果列表,而是等待您要求下一个结果,然后再调用
f
并产生它。这样可以避免在代码中生成不必要的列表,例如:

for x in map(f, iterable):    # do something with x

如果

map
急切的话
iterable
,执行循环将消耗两倍的内存,而懒惰
map
的话,所需的唯一空间
x
基本上是。

此外,它可以调用

map
无限iterables
一样
count()
。这显然导致程序永无休止地做某事,或者在某个时候您可以停止调查
map
。渴望
map
不能处理这种情况。

如果您想使用仅适用于纯功能并且允许随机访问的受限映射,则可以编写自己的类:

class PureMap:    def __init__(self, function, sequence):        self._f = function        self._sequence = sequence    def __iter__(self):        return map(self._f, self._sequence)    def __getitem__(self, i):        return self._f(self._sequence[i])    # etc.

但是,即使在这种情况下,您仍然会遇到一些问题:

  1. 如果

    sequence
    实际上是
    iterable
    ,则要获取第n个元素,则必须消耗前n个元素。之后,您必须将它们作为序列存储在类中,以备将来使用。但这已经违反了整件事的目的,因为这样做
    PureMap(f, sequence)[1000]
    需要您始终将
    1000
    元素存储在内存中, 即使它避免了对的
    999
    调用
    f

  2. 您要避免

    f
    在同一元素上多次调用。这意味着您还必须跟踪已计算出哪个元素,而未计算出哪个元素。

可以实现所需目标的唯一情况如下:

  • 被调用的函数是纯函数
  • 可迭代的参数类似于这样
    range
    ,它允许随机访问而不必产生其他元素
  • 您调用的函数很快,因此您可以在各种元素上重新计算它,而不必过多担心性能。

当所有这些假设都满足时,您可以拥有一个“像

range
”一样工作的地图对象。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5654190.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存