python中lambda表达式,列表生成式,map()函数的基础用法详解


Author:qyan.li

Date:2022.4.28

Topic:lambda表达式,列表生成式,map函数简介及使用方法分析

Reference:https://zhuanlan.zhihu.com/p/163065966https://zhuanlan.zhihu.com/p/163065966

一、写在前面:

       ~~~~~~        最近在学习QT界面创建时,部分组件(如Button)的connect函数内部参数有时需要传入lambda表达式辅助的函数,故系统了解下lambda表达式基本用法,并附带介绍其中常用的另外两种技术。

二、lambda表达式:

       ~~~~~~       lambda表达式总结起来就一句话:简单函数的一种便捷定义和表达方式,支持参数传入

       ~~~~~~       可以再使用比较详尽的语言解释一下:lambda表达式可以简化简单函数编写的难度,以一种较为简便的方式实现函数的定义和使用。当然,这只是我自己一种简单的理解方式,但是应对大多数的lambda表达式场景足够。

举几个简单的栗子,方便大家理解:

func = lambda x,y : x+y
func(1,2)

       ~~~~~~        解释一下,此函数名称为func,接收两个参数下x,y,函数内部完成的操作为x+y,相比于复杂的函数定义,这种方式显然要简单一些。

def func(x,y):
	return x + y

       ~~~~~~        当然,如果大家原意,也完全和其他基础语法进行结合,比如if else或者for循环,同样举个栗子说明一下:

func = lambda x,y : x+y if x > 0 and y < 0 else None
func(1,-6) 

       ~~~~~~       上述代码段即展示将lambda表达式和if else示例结合起来,此处不展示lambda表达式和for循环结合的示例,大家感兴趣可以参考Reference中的链接,其中有介绍。

       ~~~~~~       此处不介绍的原因在参考博文中也有提及,是因为并不推荐大家使用,因为lambda表达式和for循环结合,很大程度上可能会降低代码的可读性,但是我们使用lambda表达式的目的在于简化代码,如果简洁性的获得以牺牲代码可读性为代价,就得不偿失啦。

三、列表生成式:

       ~~~~~~       上述介绍中提到lambda表达式和for循环的结合不推荐,但我们部分场景中确实需要简化for循环的使用,比如生成1-100数平方的列表的需求:

假设传统for循环:

lst = []
for i in range(1,101):
    lst.append(i**2)

       ~~~~~~        但是,假设借助于列表生成式,代码就变成这种样子:

lst = [i**2 for i in range(1,101)]

       ~~~~~~        很明显,两段代码相比,后一种的代码简化很多。因此,在部分场景下,列表生成式的优势还是很明显的,当然它也可以结合if判断或者函数使用:

## 列表生成式结合if判断
lst = [i**2 for i in range(1,101) if i%2 == 0]
## 列表生成式结合函数
def isPremier(num):
    if num < 2:
        return -1
    else:
        for i in range(2,num):
            if num%i == 0:
                return 0
            else:
                continue
    
    return num

PremireLst = [num for num in range(2,101) if isPremier(num) != 0]
print(PremireLst)  

       ~~~~~~       写到这里,列表生成式的基本用法已经讲解完毕,做一下小的总结:

列表生成式,简单讲,就是生成列表的一种简洁方法,可以和if else和函数结合,简化生成操作

四、map()函数使用:

       ~~~~~~        此处为什么会提及map()函数呢?因为map()函数的使用一般情况下都会和是lambda表达式结合起来,故在此处提及一下map()函数。

       ~~~~~~        首先,还是先看一个简单的栗子,将列表中的字符串转换为大写的字符串:

## 借助于map函数和lambda表达式
lst = list(map(lambda x : x.upper(),["beijing","shanghai","gaungzhou"]))
lst

       ~~~~~~        借助于上述代码即可实现给定需求,同时简化代码,看到这里有的同学可能会思考,这个好像使用列表生成式也可以,甚至更简单:

lst = [x.upper() for x in ["beijing","shanghai","gaungzhou"]]

       ~~~~~~       那么,二者有什么区别呢?这就必须了解map函数的功能和使用方法:

       ~~~~~~       map()函数个人理解,是一个映射函数,内部传入参数(func,iterable),这两个参数是必备的,作用分别是func定义对于iterable对象中每个元素所进行的操作,iterable定义操作的目标对象,iterable对象即可(python的内建类型list,tuple,dict)都是可迭代的。

       ~~~~~~       阅读完上述描述,会发现,map()函数的作用本质上和列表生成式类似。而且,从实际应用看,作用也确实差不多。但是可能相对讲,map()函数更规范,同时迭代对象也更多元化,可进行的变换也相对多一些,因此,大家在阅读部分AI算法时,会发现其中非常喜欢使用map函数

提醒一些小Tips:

  1. 列表生成式必须左右两侧添加[],否则会报错
  2. map()函数在python2.0中返回值为list类型,但是在python3.0中返回值为map

五、总结:

  1. lambda表达式,列表生成式,map()函数都是为简化代码的复杂性,但是绝对不能是以牺牲代码的可读性为代价
  2. 实际应用中,lambda+map和列表生成式的作用是类似的,但是lambda+map处理问题的能力和广度比列表生成式要大一些

六、写在最后:

       ~~~~~~       文章结尾,猛然想起一个问题,了解这些的初衷目的是为解决QT中遇到的问题,所以在结尾处还是简单说一下这个问题:

       ~~~~~~       老样子,还是先看代码:

## 使用lambda表达式(传入函数名称+参数)
button1.clicked.connect(lambda: self.onClicked(button1))
def onClicked(self, button):
        print("Button {0} is clicked.".format(button.text()))

## 直接传入参数名称
button.clicked.connect(self.onOKClicked)
    def onOKClicked(self):
        items = ["C++", "Python", "Java", "Go"]
        item, ok = QInputDialog.getItem(self, "Select an Item", "Programing Language", items, 1, True)
        if ok and item:
            print("selected item: ", item)

       ~~~~~~       代码内容阅读存在难度,这并没有太大的问题,我们仅需要对比两个connect函数中传入参数的差距,可见,第一个中借助于lambda表达式传入参数,第二个直接传入函数名,这为我们提供另外一种lambda表达式的实际应用场景:当函数作为参数传入同时需要携带参数时,可借助于lambda表达式,虽然我并不知道这种总结是否科学,但是上述示例确实提供另一种的方向和应用。

猜你喜欢

转载自blog.csdn.net/DALEONE/article/details/124509778