Lambda 看这一篇就够了
1. 出自等等
本着编程语言中复习比学习更重要的原则。我复习整理一下lambda这个匿名函数。
英文释义:貌似是希腊字母的第11个。
中文含义:Lambda函数是一种快速定义单行的最小函数,是从Lisp借用来的,可以用在任何需要函数的地方。
算了,来看这个麻省理工学院的例句吧。
What lambda that does, it creates on the fly a function, as the program runs. That I can then pass around.
这里的lambda是在函数运行的时候,由一个函数创建的,然后我会传递这个值。
2. 最简单的写法和用法
lambda <变量名> : <逻辑表达式> ←原始的就是那么简单的
# 1.正常写的函数 def func(x): return x * 2 print(func(3)) # 6 # 2. Lambda表达式 因为这是一个匿名的,所以如果你想命名调用这个函数,就要在前面给它一个变量赋值过去命名 func = lambda x: x * 2 print(func(3)) # 6 # 3. 也可以这样调用 print((lambda x: x * 2)(2)) """ 上面的拆解一下就是 (lambda x: x * 2)(3) = lambda 3: 2 * 2 = 3 * 2 = 6 """
还可以_这样来调用匿名函数
lambda x, y: x + y _(1, 2) # 3
3. 结合高阶函数(Higher-order function)
Lambda在配合高阶函数使用的时候有奇效。
3-1 sorted()
sorted()
函数的基本用法
sorted([5, 2, 3, 1, 4]) # [1, 2, 3, 4, 5] a = [5, 2, 3, 1, 4] a.sort() # [1, 2, 3, 4, 5] # list.sort() 只有列表可以用,但是sorted,用于所有可迭代的数据 # [1, 2, 3, 4, 5] 先提取所有不重复的index,然后排序 sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'}) # 空格之后不区分大小写的写法 #['a', 'Andrew', 'from', 'is', 'string', 'test', 'This'] # key 形参的值应该是一个函数,它接受一个参数并并返回一个用于排序的键。 #这种技巧速度很快,因为对于每个输入记录只会调用一次 key 函数 sorted("This is a test string from Andrew".split(), key=str.lower)
这是官方给的一个lambda
和sorted()
进行搭配的例子
就是在key的地方添加了一个函数,这个函数返回的是列表序列为2的年龄,最后按照年龄进行排序
student_tuples = [ ... ('john', 'A', 15), ... ('jane', 'B', 12), ... ('dave', 'B', 10), ... ] >>> sorted(student_tuples, key=lambda student: student[2]) # 按照年龄进行排序 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
升级了一下,就是面向对象写法的时候也是支持的。
这里的key返回的是实例对象的属性
class Student: def __init__(self, name, grade, age): self.name = name self.grade = grade self.age = age # 这里定义了repr返回数据 def __repr__(self): return repr((self.name, self.grade, self.age)) student_objects = [ Student('john', 'A', 15), Student('jane', 'B', 12), Student('dave', 'B', 10), ] sorted(student_objects, key=lambda student: student.age) # !!注意这里的匿名函数是按照实例对象的属性
3-2 map() VS filter()
这俩基本上看起来写法是差不多的,作用猛然一看貌似也一样,但其实意思不太一样。可以看例子。
基本用法
map(函数,可迭代的数据)
← 主遍历浴火重生
def square(x): return x ** 2 map(square, [1,2,3,4,5]) # [1, 4, 9, 16, 25] # lambda写法 map(lambda x: x ** 2, [1, 2, 3, 4, 5]) [1, 4, 9, 16, 25]
filter(函数,可迭代的数据)
← 主筛选优胜劣汰
def is_odd(n): return n % 2 == 1 tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) print(tmplist) # [1, 3, 5, 7, 9] # lambda写法 tmplist = filter( lambda x: x % 2 == 1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) print(tmplist)
感觉map偏向于进行对可迭代对象内每个数据的遍历加成,filter偏向于对可迭代对象的过滤。
3-3 reduce()函数
这个函数又是叫化简函数。其实蛮有意思的。
从Python3开始就不是内置函数了,需要引入 from functools import reduce
reduce(function, iterable[, initializer]) reduce(函数, 可迭代对象[, 可选参数]) 其实这一个可选参数就是初始值。
大概的作用就是不停的将第一个元素和第二个元素用于迭代函数。
可选参数就是可以指定第一个init初始值,不写默认第一个参数就是,写了就指定了第一个初始值。
比如阶乘。
from functools import reduce from operator import mul array = [1, 2, 3, 4, 5] print(reduce(mul, array)) # 120 默认初始值为1 那就是 1*2*3*4*5=120 print(reduce(mul, array, 2)) # 240 默认初始值为2 那就是 2*1*2*3*4*5=240
结合lambda
from functools import reduce from operator import add from operator import sub from operator import mul array = [20, 1, 2, 3, 4, 5] print(reduce(add, array)) # 35 print(reduce(sub, array)) # 5 print(reduce(mul, array)) # 2400 # ----------直接使用匿名函数-------------- # print(reduce(lambda a, b: a+b, array)) # 35 print(reduce(lambda a, b: a-b, array)) # 5 print(reduce(lambda a, b: a*b, array)) # 2400
4. 列表推导式的崛起
列表推导式很大一部分上可以代替lambda
函数的作用。
所以并非所有的充当临时匿名函数作用的code都必须用lambda
,列表推导式也很好。
其实列表推导式也把上面的高阶函数的一部分功能给代替了
比如下面俩几乎是同样的 效果
# lambda函数 list(map(lambda x: x.capitalize(), ['cat', 'dog', 'cow'])) # 列表推导式 [x.capitalize() for x in ['cat', 'dog', 'cow']]
这个filter()
也是一样
# filter even = lambda x: x % 2 == 0 list(filter(even, range(11))) # 列表推导式 [x for x in range(11) if x % 2 == 0]
最后
lambda里面不能写语句。未完成待续...
附赠一个这篇文章脑图:不定期更新 未完成待续...
参考链接:https://realpython.com/python-lambda/
参考官方文档:https://docs.python.org/zh-cn/3/howto/sorting.html
共有评论(0)