itertools.imap 与整个可迭代对象的映射

Posted

技术标签:

【中文标题】itertools.imap 与整个可迭代对象的映射【英文标题】:itertools.imap vs map over the entire iterable 【发布时间】:2013-12-31 16:20:07 【问题描述】:

我很好奇http://docs.python.org/2/library/itertools.html#itertools.imap 的声明,即它描述了

sum(imap(operator.mul, vector1, vector2))

作为一种有效的点积。我的理解是 imap 提供了一个生成器而不是一个列表,虽然我理解如果你只考虑前几个元素和周围的 sum() 会更快/消耗更少的内存,但我不明白如何它的行为不同于:

sum(map(operator.mul, vector1, vector2))

【问题讨论】:

请注意,在 Python 3.x 中,itertools.imap 被简单地称为 map(类似的事情发生在 filter 等处),并获得旧的、返回列表的版本 @ 987654327@你需要做list(map(x)) 【参考方案1】:

当您开始增加迭代对象的大小时,mapimap 之间的区别会变得很明显:

# xrange object, takes up no memory
data = xrange(1000000000)

# Tries to builds a list of 1 billion elements!
# Therefore, fails with MemoryError on 32-bit systems.
doubled = map(lambda x: x * 2, data)

# Generator object that lazily doubles each item as it's iterated over.
# Takes up very little (and constant, independent of data's size) memory.
iter_doubled = itertools.imap(lambda x: x * 2, data)

# This is where the iteration and the doubling happen.
# Again, since no list is created, this doesn't run you out of memory.
sum(iter_doubled)

# (The result is 999999999000000000L, if you're interested.
# It takes a minute or two to compute, but consumes minimal memory.)

请注意,在 Python 3 中,内置 map 的行为类似于 Python 2 的 itertools.imap(因为不再需要它而被删除)。要获得“旧的map”行为,您可以使用list(map(...)),这是另一种可视化Python 2 的itertools.imapmap 彼此不同的好方法。

【讨论】:

【参考方案2】:

第一行将逐个计算累加项目的总和。第二个将首先计算整个点积,然后将整个结果存储在内存中,然后继续计算总和。因此,内存复杂度有所增加。

【讨论】:

【参考方案3】:

要注意的另一件事是“使用更少的内存”通常也意味着“运行得更快”。惰性(迭代器)版本在计算后立即使用每个产品,并将其添加到运行总和中。几乎可以肯定,乘积和运行总和都在 L1 缓存中。如果您首先计算所有产品,那么根据元素的数量,可以肯定计算的第一个产品将被踢出 L1 缓存,然后被踢出 L2 缓存,并且......这样当第二次通过时最后将它们加在一起,所有产品在内存层次结构中都很低(并且在极端情况下,必须从页面文件中读取)。

但我不清楚您所说的“看不到它的行为方式有何不同”是什么意思。最终的计算结果都是一样的。

【讨论】:

【参考方案4】:

不同之处在于imap(...)map(...)的整个输出都传递给sum()。您写道imap 返回了一个生成器,但我认为您可能认为sum(map(...)) 有一些捷径可以做同样的事情。它没有。 map() 将构造一个完整的结果列表任何东西被传递给sum()

【讨论】:

以上是关于itertools.imap 与整个可迭代对象的映射的主要内容,如果未能解决你的问题,请参考以下文章

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

.net AutoMapper(对象与对象之间的映射器) 的简单使用

可迭代对象 Iterable 与 迭代器 Iterator

Python教程·迭代可迭代对象迭代器与生成器详解

可迭代对象迭代器与生成器

可迭代对象与迭代器