0%

Python之lambda函数

这里介绍Python中的lambda函数

abstract.png

基本语法

lambda函数是匿名的,没有函数名称。表达式的结果即为函数的返回值
语法格式: lambda <参数列表> :<表达式>
使用方式:赋值给其他变量 或 作为参数传递给其他函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
title = "lambda函数基本语法"
print(f"------------ {title} -------------------")

# 无参lambda,参数列表可以省略
f1 = lambda : "Hello World"
print("f1() : ", f1())

# 有1个参数的lambda
f2 = lambda num1 : num1+500
print("f2(21) : ", f2(21))

# 有多个参数的lambda
f3 = lambda num1, num2 : max(num1,num2)
print("f3(24,18) : ", f3(24,18))
print("f3(11,37) : ", f3(11,37))

figure 1.png

组合拳

lambda 函数可与内置函数 map()、filter()、reduce()等一起组合使用,以便在集合上执行操作

map函数

map(func, *iterables)函数:其会对可迭代对象中的每个元素应用指定func函数,最终返回包含所有结果的迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from typing import Iterator

title = "map函数"
print(f"------------ {title} -------------------")

def square(num):
"""
计算平方数
"""
return num**2

nums = [1,2,3,4]
square_nums = map(square, nums)
print(f"square_nums 类型为迭代器 : {isinstance(square_nums, Iterator)}")
print(f"type(square_nums) : {square_nums}")
square_nums_list = list(square_nums)
print(f"square_nums_list : {square_nums_list}")

# 使用lambda可以大大简化代码
square_nums_tuple = tuple( map(lambda x:x**2, nums) )
print(f"square_nums_tuple : {square_nums_tuple}")

figure 2.png

filter函数

filter(func, *iterables)函数:其会对可迭代对象中的每个元素应用指定func函数,将结果为True的元素放入迭代器并返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from typing import Iterator

title = "filter函数"
print(f"------------ {title} -------------------")

def is_big_num(num):
return num > 18

nums = [37,2,47,17,22,99]
big_nums = filter(is_big_num, nums)
print(f"big_nums 类型为迭代器 : {isinstance(big_nums, Iterator)}")
print(f"type(big_nums) : {big_nums}")
big_nums_list = list(big_nums)
print(f"big_nums_list : {big_nums_list}")

# 使用lambda可以大大简化代码
big_nums_tuple = tuple( filter(lambda x:x>18, nums))
print(f"big_nums_tuple : {big_nums_tuple}")

figure 3.png

reduce函数

Python 3下,reduce(function, iterable)函数不再是内置函数,而是被移到了functools模块。其会对可迭代对象中的元素依次应用指定func函数,并将结果继续和可迭代对象中的下一个元素一起传递给这个func函数,直到处理完可迭代对象中所有元素为止。最终返回一个单一的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import functools

title = "reduce函数"
print(f"------------ {title} -------------------")

def add_two_num(a,b):
return a+b

nums = [2,7,1,3]
# 计算过程为:((2+7)+1)+3
sum1 = functools.reduce(add_two_num, nums)
print(f"sum1 : {sum1}")

# reduce重载版本,支持初值。计算过程:(((2800+2)+7)+1)+3
sum2 = functools.reduce(add_two_num, nums, 2800)
print(f"sum2 : {sum2}")

# 使用lambda可以大大简化代码
sum3 = functools.reduce(lambda a,b:a+b , nums)
print(f"sum3 : {sum3}")

figure 4.png

函数式编程模块:operator模块

Python提供了operator模块,其可创建一系列函数,避免开发者自己写lambda表达式

算术运算符

operator 模块为大多数算术运算符提供了相应的函数,从而避免编写lambda表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import operator

title = "算术运算符"
print(f"------------ {title} -------------------")

num1, num2 = 3, 7

add_lambda = lambda a,b : a+b
print(f"num1 + num2 = {add_lambda(num1, num2)}")
print(f"num1 + num2 = {operator.add(num1, num2)}")

mul_lambda = lambda a,b : a*b
print(f"num1 * num2 = {mul_lambda(num1, num2)}")
print(f"num1 * num2 = {operator.mul(num1, num2)}")

figure 5.png

itemgetter函数

其会自行创建函数。其创建的函数接受一个集合,返回相应索引位置(或字典中相应Key)所对应的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import operator

title = "itemgetter函数"
print(f"------------ {title} -------------------")

names = ["Bob", "Tony", "Davlid", "Amy", "Lucy"]

second_element_lambda = lambda seq : seq[1]
last_element_lambda = lambda seq : seq[-1]
odd_element_lambda = lambda seq : (seq[1], seq[3])

print( f"second_element_lambda(names) : {second_element_lambda(names)}" )
print( f"last_element_lambda(names) : {last_element_lambda(names)}" )
print( f"odd_element_lambda(names) : {odd_element_lambda(names)}" )

second_element_func = operator.itemgetter(1)
last_element_func = operator.itemgetter(-1)
odd_element_func = operator.itemgetter(1,3)

print( f"second_element_func(names) : {second_element_func(names)}" )
print( f"last_element_func(names) : {last_element_func(names)}" )
print( f"odd_element_func(names) : {odd_element_func(names)}" )

people_info = {"Aaron":34, "Tony":20, "Lucy":71}

get_tony_age_lambda = lambda map : map["Tony"]
print( f"get_tony_age_lambda(names) : {get_tony_age_lambda(people_info)}" )
# itemgetter函数也支持字典的Key
get_tony_age_func = operator.itemgetter("Tony")
print( f"get_tony_age_func(names) : {get_tony_age_func(people_info)}" )

figure 6.png

attrgetter函数

其会自行创建函数。其创建的函数接受一个对象实例,返回相应实例的属性值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import operator

title = "attrgetter函数"
print(f"------------ {title} -------------------")

class Student:
def __init__(self, name, age, birth_place):
self.name = name
self.age = age
self.birth_place = birth_place

class Location:
def __init__(self, province,city):
self.province = province
self.city = city

stu1 = Student( "Tony", 12, Location("内蒙古","呼和浩特") )
stu2 = Student( "Bob", 37, Location("黑龙江","齐齐哈尔") )

stu_info_lambda = lambda stu_info : (stu_info.name, stu_info.birth_place.city)
print( f"stu_info_lambda(stu1) : {stu_info_lambda(stu1)}" )

stu_info_func = operator.attrgetter("name", "birth_place.city")
print( f"stu_info_func(stu2) : {stu_info_func(stu2)}" )

figure 7.png

methodcaller函数

会自行创建函数。其创建的函数会在对象上调用参数指定的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import operator

title = "methodcaller函数"
print(f"------------ {title} -------------------")

msg = "Hello World"
print(f"msg.upper() : {msg.upper()}" )

my_upcase_lambda = lambda msg : msg.upper()
print( f"my_upcase_lambda(msg) : {my_upcase_lambda(msg)}" )

my_upcase_func = operator.methodcaller('upper')
# my_upcase_func(msg): 相当于 msg.upper()
print(f"my_upcase_func(msg) : {my_upcase_func(msg)}" )


msg ="This is a demo"
print(f"msg.replace(' ', '-') : {msg.replace(' ', '-')}")

my_replace_lambda = lambda msg : msg.replace(' ', '-')
print( f"my_replace_lambda(msg) : {my_replace_lambda(msg)}" )

my_replace_func = operator.methodcaller('replace', ' ', '-')
# my_replace_func(msg): 相当于 msg.replace(' ', '-')
print(f"my_replace_func(msg) : {my_replace_func(msg)}")

figure 8.png

partial函数

其会自行创建函数。其创建的函数可对指定的函数固定一部分实参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import functools

title = "partial函数"
print(f"------------ {title} -------------------")

def foo(prefix, msg, count, separator="*"):
if count > len(msg):
count = len(msg)
msg = msg[:count]
msg = prefix + msg
msg = msg.replace(" ", separator)
return msg

msg = "This is a demo 1"
print(f"foo('hello word', msg, 12, '-' ) : {foo('hello word', msg, 12, '-' )}")

foo1 = functools.partial(foo, "hello word", msg)
print(f"foo1(12, '-') : {foo1(12, '-')}")

foo2 = functools.partial(foo, "hello word", msg, separator="-")
print(f"foo2(12) : {foo2(12)}")

print("-----------------------")

print( f"foo --->>> {foo}" )
# 查看原函数
print( f"foo2.func --->>> {foo2.func}" )
# 查看固定的位置参数信息
print( f"foo2.args --->>> {foo2.args}" )
# 查看固定的关键字参数信息
print( f"foo2.keywords --->>> {foo2.keywords}" )

figure 9.png

partialmethod函数

其与partial函数类似,但后者用于固定函数的参数,前者则被用于固定方法的参数。但partialmethod函数的用法是在类的定义中,而非直接用在实例上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import functools

title = "partialmethod函数"
print(f"------------ {title} -------------------")

class Dog:
def __init__(self, name):
self.name = name

def say(self, join, msg):
print(f"{self.name} {join} {msg}")

say_hello = functools.partialmethod(say, msg="Hello")

say_bye = functools.partialmethod(say, msg="Bye~~~~")

dog1 = Dog("Bob")
dog1.say("->>>", "Hello")
dog1.say_hello("->>>")

dog2 = Dog("Tony")
dog2.say("===", "Bye~~~~")
dog2.say_bye("===")

figure 10.png

参考文献

  1. Python编程·第3版:从入门到实践 Eric Matthes著
  2. Python基础教程·第3版 Magnus Lie Hetland著
  3. 流畅的Python·第1版 Luciano Ramalho著
请我喝杯咖啡捏~

欢迎关注我的微信公众号:青灯抽丝