itertools.imap与整个iterab上的映射

2024-09-20 04:05:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我很好奇http://docs.python.org/2/library/itertools.html#itertools.imap中的一个语句,即它描述了

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

作为一个有效的点产品。我的理解是,imap提供的是一个生成器而不是一个列表,虽然我知道如果只考虑前几个元素和周围的sum(),它将如何更快/消耗更少的内存,但我看不出它的行为有什么不同于:

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

Tags: orghttpdocs列表产品htmllibrary语句
3条回答

当你开始增加迭代内容的大小时,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之间差异的好方法。

另一件需要注意的事情是,“使用更少的内存”通常也意味着“运行得更快”。lazy(迭代器)版本一计算出每个产品,就将其消耗掉,并将其添加到运行总和中。产品和运行总和几乎都肯定在一级缓存中。如果首先计算所有产品,那么根据元素的数量,可以确定计算的第一个产品将从一级缓存中踢出,然后从二级缓存中踢出,并且。。。因此,当第二次将它们相加时,所有的产品在内存层次结构中都很低(最极端的是,必须从分页文件中读取)。

但我不清楚你所说的“看不出它的行为有什么不同”。无论哪种方式,最终的计算结果都是相同的。

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

相关问题 更多 >