使用Python 3+,map()
函数返回一个地图对象(<map object at 0x01E7E150>
)而不是列表,当我试图找出原因时,一些帖子(如this)表明它有助于更好的内存管理和性能。
由于我是Python的新手,所以我真的无法完全理解“如何”它可以帮助更好的内存管理和性能。我能想到的最好 - 假设map()
返回列表对象而不是返回地图对象,那么我不需要将地图对象转换为像list(map(.....))
这样的列表,但是因为地图对象被返回所以无论如何在下一步中,我必须调用list()
函数。
我知道一个参数可能是你可以直接循环遍历地图对象,但那时还要分配内存并传递给map()
的函数必须进行评估然后如果它有什么不同我现在还是一步之后呢?
<小时/> 更新:建议这可能是this的可能重复,但我不是那个答案全面回答有关“内存管理”和“性能”的好处。
答案 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程序员的重要组成部分。