python map vs itertools.map:使迭代器版本表现得像前者

Posted

技术标签:

【中文标题】python map vs itertools.map:使迭代器版本表现得像前者【英文标题】:python map vs itertools.map: Make the iterator version behave like the former 【发布时间】:2012-12-14 22:05:38 【问题描述】:

考虑以下示例代码。给出这个例子只是为了强调mapitertools.imap 之间的不同功能。我真正想做的不可能是 完成列表理解,因为在我的真正问题中,我不是创建一个列表,而是用小数组填充一个更大的 numpy 数组。所以响应下面的代码,请不要提示:[f(x) for x in range(3)]

例子:

g = []

def f(x):
    g.append(x)

我使用map 和 itertools.map 得到的结果:

map(f, range(3)) # Results in g = [0,1,2]

itertools.imap(f, range(3)) # Does not change g

我希望 gmap 函数所做的那样进行更改。 但是,我听说map 会(或确实)表现得像 itertools.imap 在 Python 3 中。即使我使用的是 Python 2.7,我也想学习使用迭代器版本的地图的正确方法。如何使用itertools.imap实现 与map 得到的结果相同?

我能做到:

b = itertools.imap(f, range(3))
list(b) # This gives g = [0,1,2] if starting with an empty g.

这是正确的方法,还是有更好的方法?

提前致谢。

【问题讨论】:

【参考方案1】:

itertools 函数返回生成器;它们仅在迭代时运行。所以 itertools.imap(f, range(3)) 实际上不会任何事情,直到你运行它完成,例如list

根据http://docs.python.org/2/library/itertools.html#recipes,使用迭代器的最有效方式是使用长度为零的双端队列:

collections.deque(itertools.imap(f, range(3)), maxlen=0)

但是,如果你调用一个函数是为了它的副作用,你应该使用命令式而不是函数式语法:

for i in range(3):
    f(i)

【讨论】:

感谢有关 collections.deque() 的信息和有关循环的提示。我会调查的。在这种情况下,我不能使用循环,因为我最终想使用 picloud,如果我想同时运行作业(列表中的每个值一个作业),这需要我使用 cloud.map。我知道 cloud.map 与内置地图不同。但是,我想保持本地版本的代码和我在 picloud 上运行的相似。只是为了确保我以后可以在需要时使用 cloud.map。另外,map 不是比 for 循环快吗? 我不同意总是使用显式循环,如果性能相关,mapimap 和列表推导的隐式循环会更快。 @Curious2learn 不,没有理由假设 map 比 for 循环更快(例如,map 需要收集其结果,即使它们立即被丢弃)。我会谨慎申请cloud.map;它的全局变量可变性方法可能不适用于您对 g 的修改。 @ecatmur python.org/doc/essays/list2str.html - 根据 BDFL,C 中的隐式循环确实提供了性能优势。 @l4mpi 这是一个非常特殊的情况,其中查找循环函数的开销支配了调用开销。不过,要点是。【参考方案2】:

您错误地使用了map()。它不应用于函数调用的副作用,而应用于转换可迭代对象。

您可以使用list(itertools.imap(f, range(3))) 来获得您想要的行为,但我认为您应该更改整个方法以使用普通的 for 循环:

for i in range(3):
    f(i)

这表明 f() 调用的返回值没有被使用。

【讨论】:

据我所知itertools.imapmap 一样,使用隐式循环,应该比显式循环更快。【参考方案3】:

不同之处在于 Python 2.x 中的 map 相当于 Python 3 中的 list(map(...))。就是这样 - 没什么特别的......

【讨论】:

以上是关于python map vs itertools.map:使迭代器版本表现得像前者的主要内容,如果未能解决你的问题,请参考以下文章

Flux 和 Mono 中的 compose() vs. transform() vs. as() vs. map()

map (vs) unordered_map 以对为键

code map在VS2017里面找不到

.map() vs .forEach() vs for() 如何选择?

gcc 在 VS 上使用 ext/hash_map 编译库

VS生成Map文件