zep*_*hyr 4 python lazy-evaluation map-function
我最近读到mapPython 3 中的一个好处是它很懒.这意味着,做得更好
map(lambda x: x**2, range(10**100))
Run Code Online (Sandbox Code Playgroud)
而不是
[x**2 for x in range(10**100)]
Run Code Online (Sandbox Code Playgroud)
我很好奇的是,我如何能够使用这种懒惰.如果我生成地图对象,我怎么能访问结果操作/列表中的特定元素.在几乎每一个文档,map我所看到的,他们会做这样的事情print(map(...))或for i in map(...)其中(据我所知)放弃懒概念,因为它隐含映射到一个列表转换.
我想我正在寻找的是能够以类似的懒惰方式使用地图对象,就像range我可以做的那样,懒散x = range(10**100)地生成x[10000]而没有巨大的计算负荷.
如果这个概念不存在,那么map懒惰的好处是什么?如果你总是需要把它转换成一个非懒惰的对象,比如列表,为什么map懒惰呢?
你在这里比较苹果和橘子.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
Run Code Online (Sandbox Code Playgroud)
如果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.
Run Code Online (Sandbox Code Playgroud)
但即使在这种情况下,您也会遇到一些问题:
如果sequence实际上是iterable获取第n个元素,则必须使用前n个元素.之后,您必须将它们作为序列存储在您的班级中以备将来使用.但是这已经打败了整个事情的目的,因为无论如何都PureMap(f, sequence)[1000]要求你将1000元素存储在内存中,即使它避免了999调用f.
您希望避免f在同一元素上多次调用.这意味着您还必须跟踪哪些元素已经计算,哪些元素没有.
您可以实现您想要的唯一情况如下:
range允许随机访问而不必生成其他元素当满足所有这些假设时,您可以拥有一个"工作得像range" 的地图对象.
| 归档时间: |
|
| 查看次数: |
1968 次 |
| 最近记录: |