Python3入门与进阶笔记(七):函数

 

目录

一、匿名函数

二:匿名函数 + 内置函数

三、递归函数

四、函数式编程


 

一、匿名函数

第一,lambda 是一个表达式(expression),并不是一个语句(statement)。

  • 所谓的表达式,就是用一系列“公式”去表达一个东西,比如x + 2、 x**2等等;
  • 而所谓的语句,则一定是完成了某些功能,比如赋值语句x = 1完成了赋值,print 语句print(x)完成了打印,条件语句 if x < 0:完成了选择功能等等。
  • 因此,lambda 可以用在一些常规函数 def 不能用的地方,比如,lambda 可以用在列表内部,而常规函数却不能。

第二,lambda 的主体是只有一行的简单表达式,并不能扩展成一个多行的代码块。

  • 理论上来说,Python 中有匿名函数的地方,都可以被替换成等价的其他表达形式。一个 Python 程序是可以不用任何匿名函数的。不过,在一些情况下,使用匿名函数 lambda,可以帮助们大大简化代码的复杂度,提高代码的可读性。

作用:简化函数定义

格式:lambda 参数1[,参数2,...]: 运算
我们可以看到匿名函数和add函数的功能是一样的,通常不需要频繁调用且函数体简单的可以用匿名函数。 下面我们来类比一下:

  • 匿名函数没有名字,故也不存在类似add这样的函数名。
  • 我们可以看到lambda关键字后面是参数列表,相当于add的形参列表
  • 我们可以看到:后面的a+b,其实就是针对参数的运算并返回, 类似于return
  • 匿名函数的使用,我们可以看到可以通过add()调用,也可以将add的地址赋给f,通过f()调用。匿名函数lambda a, b: a + b同样也可以将其赋给s,通过s()调用,我们注意一下,这边s = lambda a, b: a + b,仅相当于定义匿名函数,并将该函数的地址赋给s,并没有调用
def add(a, b):
    return a + b
f = add
print(f, add, f(1, 3), add(1, 3))

s = lambda a, b: a + b
print(s, s(1, 3))
<function add at 0x12ab16700> <function add at 0x12ab16700> 4 4
<function <lambda> at 0x12ab16160> 4

这边我们注意一下,(lambda x: x * x) (x),之前我们遇到的大多只要写lambda x: x * x就好了,不需要自己主动调用,例如sort()、map()等,这边需要我们主动调用,(lambda x: x * x) (x),我们看到用def时,square()也是要主动调用的,下面我们会看到在sort、map中自定义函数也不需要主动调用。

[(lambda x: x*x)(x) for x in range(10)]
def square(x):
    return x ** 2
[square(x) for x in range(10)]

 

函数可以作为另一个函数的实参,匿名函数也是函数,所以匿名函数可以作为参数传递给另一个函数func,并且在func中可以调用。

def func(x, y, lambda_func):
    print(lambda_func)
    print(lambda_func(x, y))
func(1, 2, lambda a, b: a + b)
<function <lambda> at 0x12b2c4550>
3
l = [(1, 20), (3, 0), (9, 10), (2, -1)]
l.sort(key=lambda x: x[1]) # 按列表中元组的第二个元素排序

def get_second_value(item):
    return item[1]

l = [(1, 20), (3, 0), (9, 10), (2, -1)]
l.sort(key=get_second_value) # 按列表中元组的第二个元素排序

 

二:匿名函数 + 内置函数

def compare(item):
    return item.get('a')
list_dic = [{'a': 2, 'b': 3}, {'a': 0, 'b': 7}, {'a': 5, 'b': 1}]
print(max(list_dic, key=lambda item: item.get('a')))
print(max(list_dic, key=compare))
{'a': 5, 'b': 1}
{'a': 5, 'b': 1}

函数 map(function, iterable) 的第一个参数是函数对象,第二个参数是一个可以遍历的集合,它表示对 iterable 的每一个元素,都运用 function 这个函数,最后返回一个新的可遍历的集合。

def add_2(item):
    return item + 2
l = [1, 2, 3, 4]
print(list(map(lambda item: item + 2, l)))
print(list(map(add_2, l)))
[3, 4, 5, 6]
[3, 4, 5, 6]

 lambda关键字也可以与if语句结合使用,例如,下面的表示对奇数加一。

s = lambda x: x if x % 2 == 0 else x + 1
print(s(11))
l = [1, 2, 7, 4]
print(list(map(lambda x: x if x % 2 == 0 else x + 1, l)))
squared = list(map(lambda x: x**2, [1, 2, 3, 4, 5]))

def square(x):
    return x ** 2

squared = list(map(square, [1, 2, 3, 4, 5]))

 reduce(function, iterable) 函数,它通常用来对一个集合做一些累积操作。function 同样是一个函数对象,规定它有两个参数,表示对 iterable 中的每个元素以及上一次调用后的结果,运用 function 进行计算,所以最后返回的是一个单独的数值。

reduce() 函数会对参数序列中元素进行累积。函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:

  • 用传给 reduce 中的函数 function(有两个参数)
  • 先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。

若有初始值,函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:

  • 用传给 reduce 中的函数 function(有两个参数)
  • 先对初始值和集合中的第 1个元素进行操作,得到的结果再与第2个数据用 function 函数运算,最后得到一个结果。
from functools import reduce
t1 = (1, )
print(reduce(lambda x, y: x - y, t1))
print(reduce(lambda x, y: x - y, t1, 10)) 

print('=' * 30)

t1 = [1, 2, 3, 5]
print(reduce(lambda x, y: x - y, t1)) # 1 - 2 = -1, -1 - 3 = -4, -4 - 5 = -9
print(reduce(lambda x, y: x - y, t1, 10)) # 10 -1 = 9, 9 - 2 = 7, 7 - 3 = 4, 4 - 5 = -1
1
9
==============================
-9
-1
from functools import reduce
l = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, l) # 1*2*3*4*5 = 120

def my_product(a, b):
    return a * b
l = [1, 2, 3, 4, 5]
product = reduce(my_product, l) # 1*2*3*4*5 = 120

filter: filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。

接下来来看 filter(function, iterable) 函数,它和 map 函数类似,function 同样表示一个函数对象。filter() 函数表示对 iterable 中的每个元素,都使用 function 判断,并返回 True 或者 False,最后将返回 True 的元素组成一个新的可遍历的集合。

students= [{'name': 'Lily', 'age': 20}, {'name': 'Lucy', 'age': 22}, 
           {'name': 'Ami', 'age': 19}, {'name': 'Jolie', 'age': 17}]
filter_stu =list(filter(lambda stu: stu['age'] >= 20, students))
sorted_stu = sorted(students, key=lambda stu: stu.get('age'))
print('students: {}'.format(students))
print('filter_stu: {}'.format(filter_stu))
print('sorted_stu: {}'.format(sorted_stu))
students: [{'name': 'Lily', 'age': 20}, {'name': 'Lucy', 'age': 22}, {'name': 'Ami', 'age': 19}, {'name': 'Jolie', 'age': 17}]
filter_stu: [{'name': 'Lily', 'age': 20}, {'name': 'Lucy', 'age': 22}]
sorted_stu: [{'name': 'Jolie', 'age': 17}, {'name': 'Ami', 'age': 19}, {'name': 'Lily', 'age': 20}, {'name': 'Lucy', 'age': 22}]
l = [1, 2, 3, 4, 5]
new_list = list(filter(lambda x: x % 2 == 0, l)) # [2, 4]

def get_even(x):
    return True if x % 2 == 0 else False 

l = [1, 2, 3, 4, 5]
new_list = list(filter(get_even, l)) # [2, 4]

三、递归函数

# 计算0-10的和
def sum(i):
    if i == 10:
        return 10
    return sum(i + 1) + i
print(sum(0))

def sum(i):
    if i == 0:
        return 0
    return sum(i - 1) + i
print(sum(10))
55
55

关于递归过程的解释 

 

四、函数式编程

所谓函数式编程,是指代码中每一块都是不可变的(immutable),都由纯函数(pure function)的形式组成。这里的纯函数,是指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出,没有任何副作用。

def multiply_2(l):
    for index in range(0, len(l)):
        l[index] *= 2
    return l

这段代码就不是一个纯函数的形式,因为列表中元素的值被改变了,如果我多次调用 multiply_2() 这个函数,那么每次得到的结果都不一样。要想让它成为一个纯函数的形式,就得写成下面这种形式,重新创建一个新的列表并返回。

函数式编程的优点,主要在于其纯函数和不可变的特性使程序更加健壮,易于调试(debug)和测试;缺点主要在于限制多,难写。当然,Python 不同于一些语言(比如 Scala),它并不是一门函数式编程语言,不过,Python 也提供了一些函数式编程的特性,值得我们了解和学习。

def multiply_2_pure(l):
    new_list = []
    for item in l:
        new_list.append(item * 2)
    return new_list

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值