首页 > 解决方案 > 为什么map和filter函数在python3中返回迭代器?

问题描述

为什么map和filter函数在python3中返回迭代器,而reduce返回折叠操作本身?我们通过返回迭代器获得了哪些性能/内存增益?

地图返回“地图”对象:

>>> numbers = [1,2,3,4,5]
>>> map(lambda x:x*x , numbers)
<map object at 0x103e01f28>

Reduce 直接返回我折叠操作本身的结果

>>> words = ['apple', 'pineapple', 'pear', 'mango']
>>> reduce(lambda word1,word2: word1 if len(word1) > len(word2) else word2 ,words)
'pineapple'

而过滤器再次返回“过滤器:对象:

>>> numbers = [1,2,3,4,5]
>>> filter(lambda x:x%2 == 0,numbers)
<filter object at 0x103e07c18>

标签: python

解决方案


filtermap返回迭代器。您可以通过包装在列表中将它们转换为列表

numbers = [1,2,3,4,5]
list(map(lambda x:x*x , numbers))
# [1, 4, 9, 16, 25]

为什么与 没有一致性reduce?因为reduce返回单个值。它返回一个迭代器是没有意义的。


为什么mapfilter返回列表?好吧,他们曾经这样做过,但后来它被更改为 python 3,并且有充分的理由。惰性迭代器很有用,因为我们不会在N每次使用时都创建一个新的值列表。这意味着它们可以按顺序使用

map(operator.truediv, filter(lambda t: t[1] != 0, zip(itr1, itr2)))

无需创建不必要的大数据块。


要回答评论中的问题:

不,map不仅filter在上述示例中完成后应用。证明:

def verbose_count():
   i = 0
   while True:
       print(f'generating {i}')
       yield i
       i += 1

itr = map(lambda x: x * x, filter(lambda x: x % 2 == 0, verbose_count()))


next(itr)
generating 0
Out[2]: 0

next(itr)
generating 1
generating 2
Out[3]: 4

filter -> map正如你所看到的,当我没有传递所有值时,我可以获得序列的输出(我什至传递了一个永远不会完成的无限生成器)。


推荐阅读