如何通过map()函数返回地图对象有助于更好的内存管理和性能

时间:2018-03-22 18:28:29

标签: python

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

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

我知道一个参数可能是你可以直接循环遍历地图对象,但那时还要分配内存并传递给map()的函数必须进行评估然后如果它有什么不同我现在还是一步之后呢?

<小时/> 更新:建议这可能是this的可能重复,但我不是那个答案全面回答有关“内存管理”和“性能”的好处。

1 个答案:

答案 0 :(得分:0)

Python 3&#39; s 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方法可以在请求下一行之前将每一行写入磁盘。如果文件很大(多个千兆字节,可能超过一次可以容纳在内存中),这非常非常重要。

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

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

如果map生成了一个列表,则需要在迭代发生之前将昂贵的操作应用于前面输入的所有值。

(请注意,我通常不会使用map来编写这些示例中的任何一个,我只是编写一个显式的for循环并自己应用该函数,但是{{1也很好。)

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