Python高阶函数filter、map、reduce的使用

试想一下,Python是一门怎样的语言?

没错,简单、优雅、易懂是它最明显的特征。笔者刚接触Python时,便开始惊叹这门语言强大的类库支撑,这种面向调用的编程方式属实真香,虽然性能有点可惜(尺有所短,寸有所长),但笔者对Python依旧爱的深沉。

Python中有着许多好用的内建函数供开发者使用,其中有这么个函数三兄弟filter、map、reduce被称作高阶函数,由于他们的使用方法比较类似,所以联合记忆起来也比较容易。

filter

filter主要用来过滤序列,可以理解为一个过滤器。

filter(function or None, iterable)

# function:判断函数
# iterable:可迭代对象

function参数用于对iterable进行过滤,将function返回值为False的元素过滤,剩下为True的元素将组成一个filter对象被返回(Python 2.x 返回的是列表)。

# 定义函数func
def func(x):
    # x大于5时返回True,否则返回False
    return x > 5


num_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]

result = filter(func, num_list)

print(result)

# 输出:<filter object at 0x000001F8763751C8>

通过上述代码可看到,filter函数返回的是一个filter对象,我们可以通过类型转换使其更加友好的显示。

print(result)
# 输出:<filter object at 0x000001703525F1C8>

print(list(result))
# 转换为列表对象,输出:[6, 7, 8, 9]

print(tuple(result))
# 转换为元组对象,输出:(6, 7, 8, 9)

print(set(result))
# 转换为集合对象,输出:{8, 9, 6, 7}

需要注意的是,filter对象无法转换成字典dict,对于字典的过滤,我们需要些特殊处理,即提取value进行过滤。

def func(x):
    # x为偶数时返回True,否则返回False
    return x % 2 == 0


num_list = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

result = filter(func, num_list.values())

print(list(result))

filter可以结合匿名函数lambda使用。

num_list = [1, 2, 3, 4, 5]

# 筛选出大于2的数字
result = filter(lambda x: x > 2, num_list)
print(list(result))

# 输出:[3, 4, 5]

map

map函数会根据提供的函数对指定序列做映射。

map(function, iterable, ...)

# function:判断函数
# iterable:可迭代对象

map也是接受一个函数参数与一个迭代参数,通过函数参数对序列进行映射。

def func(x):
    # 返回x的x次方
    return x ** x


num_list = [1,2,3,4,5]

result = map(func, num_list)

print(result)
# 输出:<map object at 0x000001CEA3AB9708>

和filter类似,map函数返回的是一个map对象。同样可通过类型转换使其更加友好的显示,当然,同样的也无法转换成dict字典对象。

print(result)
# 输出:<map object at 0x000001CEA3AB9708>

print(list(result))
# 转换为列表对象,输出:[1, 4, 27, 256, 3125]

print(tuple(result))
# 转换为元组对象,输出:(1, 4, 27, 256, 3125)

print(set(result))
# 转换为集合对象,输出:{256, 1, 4, 3125, 27}

map函数还可以并行使用,非常的自由。

def func(x, y, z):
    return x * 100 + y * 10 + z


num_list1 = [1, 4, 7]
num_list2 = [2, 5, 8]
num_list3 = [3, 6, 9]

result = map(func, num_list1, num_list2, num_list3)

print(list(result))
# 输出:[123, 456, 789]

map还可以用来做类型转换。

result = map(int, '1234')

for i in result:
    print(f'{i}的类型为:{type(i)}')

# 输出:
#   1的类型为:<class 'int'>
#   2的类型为:<class 'int'>
#   3的类型为:<class 'int'>
#   4的类型为:<class 'int'>

同样的,map也可以与lambda函数结合使用。

num_list = [1, 2, 3, 4, 5]

# lambda返回x的平方
result = map(lambda x: x ** 2, num_list)
print(list(result))

# 输出:[1, 4, 9, 16, 25]

reduce

reduce函数会对参数序列中元素进行累积,首先看一下reduce的语法。

from functools import reduce

reduce(function, iterable[, initializer])

# function:函数参数
# iterable:可迭代对象
# initializer:可选,初始参数

function为函数参数,iterable依旧是可迭代对象,initializer为可选的初始参数。

在python3.x中,reduce移到了functools模块中,使用时需要先引入。

from functools import reduce

num_list = [1, 2, 3, 4, 5]

result = result = reduce(lambda x, y: x * 10 + y, num_list)

print(result)
# 输出:12345

通过上述案例可发现,reduce是通过可迭代对象的前两个元素传递给函数参数进行函数加工。

然而,有初始化值的情况下,这个时候就不是取迭代对象的前两项,而是取初始参数initializer和第一个元素。

from functools import reduce

num_list=[1, 2, 3, 4]

# 初始参数initializer,即 从5开始累加
result = reduce(lambda x, y: x + y, num_list, 5)

print(result)
# 输出:15
# 即: 5 + 1 + 2 + 3 + 4 = 15

以上便是这仨兄弟函数的技术总结,值得一提的是,自1994年Python 1.0 解释器发布起,Python便存在这三个高阶函数,以及匿名函数lambda。虽然,如今的2.x及3.x在这三个函数上有些不同的语法,但无伤大雅。

Python依然是那个Python。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269