强制迭代所有迭代 [英] Force all iterations on an iterable

查看:177
本文介绍了强制迭代所有迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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 消费配方适用于此处:

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.

这篇关于强制迭代所有迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆