【问题标题】:How returning a map object by map() function helps better memory management and performance通过 map() 函数返回地图对象如何帮助更好的内存管理和性能
【发布时间】:2018-03-22 18:28:28
【问题描述】:

在 Python 3+ 中,map() 函数返回一个映射对象 (<map object at 0x01E7E150>) 而不是列表,当我试图找出原因时,一些帖子(如 this)表明它有助于更​​好的内存管理和性能。

由于我是 Python 新手,所以我真的无法完全理解“如何”它可以帮助更好的内存管理和性能。我能想到的最好的是-假设如果map()返回了列表对象而不是返回地图对象,那么我不需要像list(map(.....))那样将地图对象转换为列表,但是由于地图对象在接下来的时候被返回了步骤我必须调用list() 函数。

我知道一个参数可能是您可以直接循环遍历 map 对象,但那时还必须分配内存并且必须评估传递给 map() 的函数,那么如果我这样做有什么不同是现在还是一步之后?


更新:建议这可能与this 重复,但我不认为该答案是全面回答有关“内存管理”和“性能”优势的问题。

【问题讨论】:

  • 粗略地说,如果你遍历 Py3 map 对象,那么你只在内存中保存可迭代的每一项,而不是整个可迭代(如 list);有关其他详细信息/差异,请参阅我建议的欺骗
  • @Chris_Rands 是的,我确实看到了你的欺骗建议,但我不认为这个答案是全面回答有关“内存管理”和“性能”优势的问题。
  • @hagrawal 请同时阅读其他答案。
  • 我不明白你不明白的地方,你了解迭代器/生成器在 Python 中一般是如何工作的吗?

标签: python


【解决方案1】:

Python 3 的 map 返回一个迭代器(您在输出中看到的 map 对象)。这个迭代器是惰性的,它一次只将函数应用于来自输入迭代器的一个值,以便产生一个输出值。当输入也是惰性迭代器时,这很方便,输出一次可以消耗一个值。

考虑这段代码:

with open(some_file) as f_in, open(some_file + ".out", "w") as f_out:
    f_out.writelines(map(line_transform_func, f_in))

这会打开两个文件,一个用于读取,一个用于写入。然后它从输入文件中读取行,对它们执行某种转换,然后将它们写入输出文件。由于文件是惰性的,因此无需一次将输入文件的全部内容读入内存。相反,您只需要足够的内存来一次读取一行。同样,由于map 返回一个惰性迭代器,转换后的行将一次生成一行,writelines 方法可以在请求下一行之前将每一行写入磁盘。如果文件很大(数 GB,可能超过一次内存的容量),这一点非常很重要。

map 作为惰性迭代器的另一个优点是,如果您提前停止对输出的迭代,它不需要在所有输入上运行其函数。例如,假设您要对大型输入序列进行昂贵的计算,但您只需要在找到满足某些条件的第一个输出之前执行此操作。您可以使用map 和带有break 语句的循环来在找到所需值后立即停止迭代:

for value in map(some_expensive_operation, input_values):
    if some_criteria(value):
        break

如果map 生成了一个列表,则需要在迭代发生之前对输入中的所有值进行昂贵的操作。

(请注意,我通常不会像使用map 那样编写这些示例中的任何一个,我只会编写一个明确的for 循环并自己应用该函数,但map 也可以正常工作。)

如果您不熟悉 Python 迭代器,我强烈建议您阅读它们。它们是 Python 工作方式的重要组成部分,理解它们(以及如何创建和使用新的惰性函数,例如使用生成器函数)是成为更熟练的 Python 程序员的重要部分。

【讨论】:

    猜你喜欢
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多