Python实用教程系列——推导式和Lambda表达式

上次推文我们一起学习了python中的高级函数——Python实用教程系列——高阶函数Map、Filter、Reduce。推文中重点介绍了map,filter和reduce中相关概念,也通过实例的方式介绍了这些函数的实际用法,大家可以好好学习一下。

有小伙伴对推导式和Lambda的相关知识不是很清楚,需要我写一些容易理解的教程,所以这次推文我们就来聊一聊推导式的相关知识。

一、推导式定义

推导式 comprehensions(又称解析式),是 Python 的一种独有特性。推导式最主要的特点就是可以从一个数据序列构建另一个新的数据序列。在Python 中目前常用的推导式有列表推导式、字典推导式和集合推导式

二、列表推导式

列表推导式是我们最常使用的,因为列表是我们最常使用的,其基本的语法示意如下:

  • [表达式 for 变量 in 列表]
  • [表达式 for 变量 in 列表 if 条件]

上述表达式中”[]”是表示Python中的列表。从基本的语法形式上我们看得出来,变量是我们预先就存在的列表的值,或者是对存在的列表进行条件筛选后的值。

我们来看几个具体的例子就清晰了:

2.1 第一种语法形式

list_a = range(1,10)
list_b = [each for each in list_a]
print(list_b)

# 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9]

2.2 第二种语法形式

# 输出 list_a中的基数

list_a = range(1,10)
list_b = [each for each in list_a if each % 2 ==1]
print(list_b)
# 输出 [1, 3, 5, 7, 9]

第二种语法形式生成的结果与第一种不同的原因在于,第二种语法形式中使用了筛选条件:each % 2 ==1

注意list_b使用了”[]”,这就说明了其为一个列表。有的小伙伴还没看出来的话,我们使用for将第二种形式进行改写:

list_b = []
list_a = range(1,10)
for each in list_a:
   if each % 2 == 1:
       list_b.append(each)
print(list_b)

输出结果为list_a中的奇数组成的列表,if each % 2 == 1在第二种形式中也完全显示了,可以看出使用列表推导式可以精简代码,阅读起来更加有Python的风格。

这里给大家设置两个小题目,大家试着解决:

(1)过滤掉列表

names = ['gongsunli’,’machao’,’Gongben’,’Yuji’]中长度大于或等于4的字符串列表,并将剩下字符的转换成大写字母,结果保存为列表。

(2)给定列表A=[a,b,c], B=[d,e,f]],找出A和B中元素可以组成的字符串的所有可能,如ab.

三、字典推导式

学习了列表推导式以后,学习字典推导式就没什么困难了,字典推导式语法差不多,只不过我们使用”{}”产生的是字典而已,唯一要注意的就是在字典中有键和值两个关键的属性,仿似列表推导式,那么其基本的语法可以被写作这样:

  • { 键:值 for 键,值 in 数据结构}
  • { 键:值 for 键 in 数据结构1 for 值 in 数据结构2 }

同样我们来看几个实际的小例子:

3.1 第一种语法形式

list_c = ['我爱','Python学堂']
dict_c = {k:v for v,k in enumerate(list_c)}
print(dict_c)
# 输出:{'我爱': 0, 'Python学堂': 1}

3.2 第二种语法形式

list_a = ['我爱']
list_b = ['Python学堂']
dict_a = {key: value for key in list_a for value in list_b}
print(dict_a)
#输出:{'我爱': 'Python学堂'}

上述代码块1中使用了Python的内置函数enumerate()。有基础的小伙伴一看就知道,enumerate()可将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据下标和数据。代码块2的最后生成的结果是一个字典(或常使用生成Json数据),第二种的字典推导式是非常常见的,大家要掌握好。

再看一个例子:

# 遍历一个有键值关系的可迭代对象
pro_city = [('江苏', '南京'), ('福建', '福州'), ('北京', '北京')]
dict_d = {key: value for key, value in pro_city}
print(dict_d)

# {'江苏': '南京', '福建': '福州', '北京': '北京'}

再如:

dict_e = {key: key * key for key in [1,2,3]}
print(dict_e)

基本上字典推导式就这些,只不过在平时的使用中我们使用一些其他的技巧就能产生一些奇妙的现象。

四、集合推导式

集合我们都很了解,就是一个没有重复元素的汇集,跟列表和字典推导式类似,其基本的语法形式可以表示为:

  • { 表达式for 项in 序列if 条件}

我们先看看集合“{}”,因为其是不重复的,因此如果有语句:print({1,2,3,4,4,5})会输出:1,2,3,4,5,重复的4将会被删除。

接着我们来看集合的相关例子:

# 遍历一个有键值关系的可迭代对象
string_var = '我爱Python学堂'
res = {value for value in string_var}
print(res)

#输出为{'h', 'y', 'o', 'P', '我', '爱', '学', 'n', '堂', 't'}

由于集合是无序性的,因此我们再次运行上述代码的时候,会得到不同的结果的,比如我们可能得到:

{'我', 'y', 'o', 't', 'h', 'n', '学', '爱', 'P', '堂'},

{'我', 't', 'o', 'y', 'n', '堂', 'h', '爱', '学', 'P'}等等。

以上就是推导式相关的内容了,我们再来看一个很好玩的东西,很酷炫的表达式:lambda表达式。

五、Lambda表达式

在Java 和Python中均提供了一个Lambda表达式,这个表达式又被称为匿名函数,是现代各种编程语言争相引入的一种语法,它设计精巧,在很大程度上可以精简代码,就像推导式一样。

我们之前的推文讲述了map、reduce、filter等函数都支持函数作为参数,而Lambda函数就可以应用在函数式编程中。其基本语法可以简述如下:

  • Lambda [参数1[参数2, … 参数n]]: 表达式

参数的数量是不固定的,可选的。

我们来看看这个函数和我们自定义的函数之间有什么差异,假设我们现在计算两个数的和:

5.1 自定义方式

def add_two(x,y):
   return x + y
print(add_two(1,2))

5.2 Lambda方式

res = lambda x,y:x+y
print(res(1,2))

他们的差别很明显:Lambda能够出现在Python语法不允许def出现的地方,def定义的函数一般用来处理比较复杂的功能,而Lambda用来处理一些简单的操作。

之前的推文中,我们讲述了一些map、reduce、filter函数,如果这些函数和Lambda结合起来使用就会产生一些比较高级的操作,比如:

5.3 与map结合

list_1=[1,2,3]
list_2=[10,20,30]
print(list(map(lambda x,y:x+y,list_1,list_2)))

#输出 [11, 22, 33]

5.4 与reduce结合

from functools import reduce
print(reduce(lambda a,b: a+b ,[1,2,3,4])) # 输出10

5.5 与filter结合

num_list = [1,2,3,3,4,5,6,7,8,9,10]
print(list(filter(lambda  x : x % 2 == 0, num_list)))
# 输出 [2, 4, 6, 8, 10]

实际使用的中,我们可能会遇道更加复杂的操作,但是没关系,只要理解好lambda的精髓这些问题就不是问题啦!

最后总结一下使用Lambda的好处:

(1)使用 Lambda 表达式可省去定义函数的过程,让代码更加简洁。

(2)Lambda 表达式具有使用后即释放的特点,从这个角度上提升了程序的性能(如内存使用)。

六、总结

本次推文我们讲述了Python中的推导式和Lambda表达式,这些表达式能很好精简代码并且使得代码更加的具又Python风格,实际项目中我们可使用它们很好解决问题,比如:leetcode中的第937题《重新排列日志》,有兴趣的小伙伴可以研究一下。

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

推荐阅读更多精彩内容