问题描述
我使用 map 编写了一个 for 循环,其函数具有副作用.这是我的意思的一个最小的工作示例:
I've written a for-loop using map, with a function that has a side-effect. Here's a minimal working example of what I mean:
def someFunc(t):
n, d = t
d[n] = str(n)
def main():
d = {}
map(somefunc, ((i,d) for i in range(10**3)))
print(len(d))
因此很明显,someFunc
映射到 1000 以下的非负数,具有填充字典的副作用,该字典稍后用于其他用途.
So it's clear that someFunc
, which is mapped onto the non-negative numbers under 1000, has the side-effect of populating a dictionary, which is later used for something else.
现在,鉴于上述代码的结构方式,print(len(d))
的预期输出为 0
,因为 map
返回一个迭代器,而不是一个列表(与 python2.x 不同).因此,如果我真的想查看应用于 d
的更改,那么我将不得不迭代该地图对象直到完成.我可以这样做的一种方法是:
Now, given the way that the above code has been structured, the expected output of print(len(d))
is 0
, since map
returns an iterator, and not a list (unlike python2.x). So if I really want to see the changes applied to d
, then I would have to iterate over that map object until completion. One way I could do so is:
d = {}
for i in map(somefunc, ((i,d) for i in range(10**3))):
pass
但这似乎不是很优雅.我可以在地图对象上调用 list
,但这需要 O(n) 内存,这是低效的.有没有办法强制对地图对象进行完整迭代?
But that doesn't seem very elegant. I could call list
on the map object, but that would require O(n) memory, which is inefficient. Is there a way to force a full iteration over the map object?
推荐答案
你不想这样做(运行 map()
只是为了副作用),但是有一个 itertools
consume
食谱 适用于此:
You don't want to do this (run a map()
just for the side effects), but there is a itertools
consume
recipe that applies here:
from collections import deque
deque(map(somefunc, ((i,d) for i in range(10**3))), maxlen=0)
collections.deque()
对象,配置为最大大小为 0,消耗 map()
可迭代,不使用额外的内存.deque
对象是特别优化 对于这个用例.
The collections.deque()
object, configured to a maximum size of 0, consumes the map()
iterable with no additional memory use. The deque
object is specifically optimized for this use-case.
这篇关于强制对一个可迭代对象进行所有迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!