专栏首页AI研习社Python编程技巧:如何用Map, Filter, Reduce代替For循环?

Python编程技巧:如何用Map, Filter, Reduce代替For循环?

你是否有过这样的经历,你查看自己写的代码并看到满眼的 for 循环?你发现你必须斜着你的眼睛,并将脑袋前倾到你的显示器,以看得更清楚。

反正我有过这样的经历。

for 循环就像是一把瑞士军刀,它可以解决很多问题,但是,当你需要扫视代码,快速搞清楚代码所做的事情时,它们可能会让人不知所措。

map、filter 和 reduce 这三种技术可以提供描述迭代原因的函数替代方案,以便避免过多的 for 循环。我之前在 JavaScript 中写过这些技术的入门文章,但是它们在 Python 中的实现略有不同。

我们将简要介绍这三种技术,主要介绍它们在 JavaScript 和 Python 中的语法差异,然后给出如何转换 for 循环的示例。

什么是 Map、Filter 和 Reduce?

回顾我以前编写的代码,我意识到 95% 的时间都花在遍历字符串或数组上。在这种情况下,我会执行以下操作之一:将一系列语句映射到每个值,筛选满足特定条件的值,或将数据集减少为单个聚合值。

有了这种洞察力,你就可以识别和实现这三种方法,即循环遍历通常属于这三种功能类别之一:

  • Map:对每个项应用相同的步骤集,存储结果
  • Filter:应用验证条件,存储计算结果为 True 的项
  • Reduce:返回一个从元素传递到元素的值

为什么 Python Map/Filter/Reduce 会不一样?

在 Python 中,这三种技术作为函数存在,而不是数组或字符串类的方法。这意味着,你将编写 map(function, my_list),而不是编写 my_array.map(function)。

此外,每个技术都需要传递一个函数,该函数将执行每个项目。通常,该函数是作为匿名函数(在 JavaScript 中称为 arrow 头函数)编写的。但是,在 Python 中,你经常看到被使用的是 lambda 表达式。

lambda 表达式和 arrow 函数之间的语法实际上非常相似。将 => 替换为 : 并确保使用关键字 lambda,其余的几乎相同。

// JavaScript Arrow Function
const square = number => number * number;
// Python Lambda Expression
square = lambda number: number * number

arrow 函数和 lambda 表达式之间的一个关键区别是,arrow 函数能够通过多个语句扩展成完整的函数,而 lambda 表达式仅限于返回的单个表达式。因此,在使用 map()、filter()或 reduce()时,如果需要对每个项执行多个操作,请先定义函数,然后再包含它。

def inefficientSquare(number):
   result = number * number
   return result
   
map(inefficientSquare, my_list)

替换 for 循环

好了,下面来点好东西。下面是三个常见的 for 循环示例,它们将被 map、filter 和 reduce 替换。我们的编程目标:计算列表中奇数平方和。

首先,使用 基本的 for 循环示例。注意:下面的代码纯粹是为了演示,即使没有 map/filter/reduce 也有改进空间。

numbers = [1,2,3,4,5,6]
odd_numbers = []
squared_odd_numbers = []
total = 0

# filter for odd numbers
for number in numbers:
  if number % 2 == 1:
     odd_numbers.append(number)

# square all odd numbers
for number in odd_numbers:
  squared_odd_numbers.append(number * number)

# calculate total
for number in squared_odd_numbers:
  total += number

# calculate average

让我们将每个步骤转换为这三个函数的其中之一:

from functools import reduce
numbers = [1,2,3,4,5,6]
odd_numbers = filter(lambda n: n % 2 == 1, numbers)
squared_odd_numbers = map(lambda n: n * n, odd_numbers)
total = reduce(lambda acc, n: acc + n, squared_odd_numbers)

有几个重要的语法要点要强调。

  • map()和 filter()本机可用。但是,reduce()必须从 Python 3 以上版本中的函数库导入
  • lambda 表达式是所有三个函数中的第一个参数,iterable 是第二个参数
  • reduce()的 lambda 表达式需要两个参数:累加器(传递给每个元素的值)和单个元素本身

记住,for 循环在代码中确实是很重要的,但是扩展工具包从来都不是坏事。

via:https://medium.com/better-programming/how-to-replace-your-python-for-loops-with-map-filter-and-reduce-c1b5fa96f43a

本文分享自微信公众号 - AI研习社(okweiwu),作者:skura

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 今日头条推荐算法原理首公开,头条首席算法架构师带来详细解读

    今天,算法分发已经是信息平台、搜索引擎、浏览器、社交软件等几乎所有软件的标配,但同时,算法也开始面临质疑、挑战和误解。今日头条的推荐算法,从2012年9月第一版...

    AI研习社
  • 专栏 | OpenCV图像处理专栏十五 |《一种基于亮度均衡的图像阈值分割技术》

    对于光照不均匀的图像,用通常的图像分割方法不能取得满意的效果。为了解决这个问题,论文《一种基于亮度均衡的图像阈值分割技术》提出了一种实用而简便的图像分割方法。该...

    AI研习社
  • 利用卷积自编码器对图片进行降噪

    前言 这周工作太忙,本来想更把 Attention tranlsation 写出来,但一直抽不出时间,等后面有时间再来写。我们这周来看一个简单的自编码器实战...

    AI研习社
  • Apache Solr Velocity模版注入远程命令执行漏洞复现以及 POC 编写

    19 年 10 月 31 日,安全研究员 S00pY 在 GitHub 发布了 ApacheSolr Velocity 模版注入远程命令执行的 POC,经过其他...

    信安之路
  • C++11:基于std::unordered_map和共享锁构建线程安全的map

    版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net/10...

    用户1148648
  • 设计模式-状态模式

    一个对象的行为取决于一个或者多个动态变化的属性,这些属性叫做状态,比如订单的支付状态;而这些订单状态的值是预先知道的,已支付、未支付;当订单在客户操作过程中可能...

    breezedancer
  • Solr单机版的安装与使用

    1 1、使用Solr实现。 2 基于Solr实现站内搜索扩展性较好并且可以减少程序员的工作量,因为Solr提供了较为完备的搜索引擎解决方案,因此在门户、论坛...

    别先生
  • 设计模式(八)——轻松学习建造者模式

    小森啦啦啦
  • 力扣题目汇总(转换成小写字母,唯一摩尔斯密码,有序数组平方)

    实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串。

    小小咸鱼YwY
  • Spring Cloud Stream使用细节

    上篇文章我们看了Spring Cloud Stream的基本使用,小伙伴们对Spring Cloud Stream应该也有了一个基本的了解,但是上篇文章中的消息...

    江南一点雨

扫码关注云+社区

领取腾讯云代金券