python - 为什么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>
解决方案
filter
并map
返回迭代器。您可以通过包装在列表中将它们转换为列表
numbers = [1,2,3,4,5]
list(map(lambda x:x*x , numbers))
# [1, 4, 9, 16, 25]
为什么与 没有一致性reduce
?因为reduce
返回单个值。它返回一个迭代器是没有意义的。
为什么map
不filter
返回列表?好吧,他们曾经这样做过,但后来它被更改为 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
正如你所看到的,当我没有传递所有值时,我可以获得序列的输出(我什至传递了一个永远不会完成的无限生成器)。
推荐阅读
- mysql - 在 SQL 中转换/转换科学记数法 [从 Varchar 到 Decimal/Numeric]
- multithreading - 场景中的 Corda FlowLogic 行为 - 这里线程的相关性是什么?
- javascript - 重新连接到已知和配对的网络蓝牙设备
- r - 通过 R 下载谷歌趋势数据
- java - 注册我的 Web 应用程序 java 时出错
- java - 如何检查一个类是否代表一个特定的原始类型
- css - 我有一个带有 positoin:absolute 的 Flatlist ,onpress 在渲染项内没有响应
- python - 关于更改函数名称的问题
- r - R:ggplot2 geom_segment 像素化
- javascript - 使用 React 在数组内映射数组