一、lambda表达式(匿名函数)
1、概念
lambda函数也叫匿名函数,即,函数没有具体的名称
1
2
3
4
5
6
7
8 def multip(x):
return x * 2
lam = lambda x : x * 2
print(multip(2))
print(lam(2))运行完成之后的结果都是4,通过结果我们可以知道,lambda在Python这种动态的语言中确实没有起到什么特别大的作用,因为有很多别的方法能够代替lambda,所以python对 ambda有比较简单有限的支持
简单来说好比电影里面的群众演员,往往他们的戏份很少,最多是衬托主演,跑跑龙套(出来就死的那种),他们需要名字吗?不需要,因为他们仅仅只是临时出镜,下次可能就用不着了,所以犯不着费心思给他们每个人编个号取个名字,毕竟取个优雅的名字是很费劲的事情
2、为什么要使用lambda
通过上面的代码,我们会发现
lambda简化了函数定义的书写形式。是代码更为简洁,但是使用函数的定义方式更为直观,易理解。
对于一些抽象的,不会别的地方再复用的函数,有时候给函数起个名字也是个难题,使用lambda不需要考虑命名的问题
3、语法格式
语法
1
lambda 形参列表 : 表达式
语法说明
- 关键字
lambda
后面紧跟着形参列表. 注意形参列表不能用圆括号括起来 - 形参列表后面紧跟着一个冒号(
:
) - 冒号后面是唯一的表达式. 注意:此表达式必须是合法的表达式.
lambda
会自动返回表达式的运算结果
- 关键字
注意事项
- lambda 表达式只是对简单到只有一行代码的函数的语法糖(简写), 如果有多行代码, 则无法使用 lambda 表达式
- lambda 函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值
- lambda用来编写简单的函数,而def用来处理更强大的任务
4、示例代码
无参
1
2
3
4
5#函数名为fun
def fun():
return Ture
#无参数 无函数名
lambda : Ture位置参数
1
2m = lambda x,y,z: x*y*z
print(m(2,3,4))关键字参数
1
2
3
4
5
6#函数
def add(x,y=2)
return x + y
#lambda表达式
add = lambda x,y=2: x+y
print(add(10))不定长参数,返回元组
1
2
3
4
5
6
7
8
9#函数定义
def fun(*args):
return args
#表达式
a = lambda *z: z * 2
if __name__ == '__main__':
print(a(1, 2, 3, 4, '姓名'))不定长参数,返回字典
1
2
3
4
5
6
7
8# 函数
def fun_kwargs(**kwargs):
return kwargs
# 表达式
c = lambda **kwargs: kwargs
if __name__ == '__main__':
print(c(arg1=1, arg2=1, arg3='姓名'))直接后面传递实参
1
2
3if __name__ == '__main__':
print((lambda x, y: x if x > y else y)(100, 200))
print((lambda x: x ** 10)(2))配合函数使用
1
2
3
4
5
6
7
8
9
10
11
12def say(name, content):
return (lambda name, content: name + 'say: ' + content)(name, content)
if __name__ == '__main__':
print(say('小明', 'Hello World'))
def action(x):
return lambda y: x+y
fun = action(2)
print(f(3))使用在不能定义函数的
1
2info = [(lambda a: a**3)(1), (lambda b: b**3)(2)]
print(info)
5、小结
- 对于单行函数,使用lambda可以省去定义函数的过程,让代码更加精简。
- 在非多次调用的函数的情况下,lambda表达式即用既得,提高性能
- 如果可以使用for…in…if来完成的,坚决不用lambda。
- 如果使用lambda,lambda内不要包含循环,如果有,我宁愿定义函数来完成,使代码获得可重用性和更好的可读性。lambda 是为了减少单行函数的定义而存在的。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda表达式是起到一个函数速写的作用。允许在代码内嵌入一个函数的定义。
二、内置函数
1、map
1.1、说明
对一个及多个可迭代对象执行同一个操作,返回一个map对象(可迭代对象)
1.2、语法格式
1 | map(func, *iterables) |
1.3、参数说明
func:
函数名,不能为None 也可以是匿名函数
iterables:
一个或者多个可迭代的对象,例如:list 字典
1.4、原理图
1.5、返回值
Python 3.x 返回map对象(迭代器)
Python 2.x 返回列表
1.6、注意
返回一个新的迭代对象,不会对原来的序列有影响,输出的时候注意因为是一个迭代对象,所有想查看结果可以通过for循环或者list()来显示
1.7、举个栗子
基本使用
1
2li = [1, 2, 3, 4, 5]
iter1 = map(lambda x: x * 2, [1, 2, 3, 4, 5])元组和列表配合使用
1
2
3#注意 传入两个可迭代对象,所以传入的函数必须能接收2个参数
iter2 = map(lambda x, y: x + y, [1, 2, 3, 4], (10, 20, 30, 40))
print(tuple(iter2))当传入多个可迭代对象时,且它们元素长度不一致时,生成的迭代器只到最短长度
1
2
3iter3 = map(lambda x, y: x + y if y else x + 10, [1, 2, 3, 4, 5], (1, 2, 3, 4))
print(tuple(iter3))
# 输出(2, 4, 6, 8)结合函数使用
1
2
3
4
5nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def fun(x):
return x * x
print(list(map(fun, nums)))
2、filter
2.1、说明
对于序列中的元素进行筛选,最终获取符合条件的序列,相当于一个迭代器,调用一个布尔函数func来迭代seq中的每个元素,返回一个是bool_seq返回为True的序列
2.2、语法格式
1 | filter(function, iterable) |
2.3、参数说明
function:
函数或None
iterable:
可迭代对象,例如: 列表 字典,集合 字符串等
2.4、返回值
- 如果参数为function,那么返回条件为真的返回迭代器对象
- 如果参数为None的话,那么返回序列中所有为True的元素
2.5、原理图
2.6、举个栗子
要过滤掉所有值为False的列表
1
2li = [1, 0, 0.0, None, {}]
filter(None, [-2, 0, 2, '', {}, ()])过滤字母(字符串)
1
filter(lambda x: x !='a','abcd')
过滤元素(列表)
1
2names = ['老宋', '老王', '小张', '小花', '小明', '']
filter(None, names)过滤列表中的奇数
1
2
3nums = [0,101,10,7,3,5,8,131,88]
if __name__ == '__main__':
filter(lambda x: x%2, nums)将2-10间所有质数列出来
1
2if __name__ == '__main__':
filter(lambda x: not [x for i in range(2,x) if x%i == 0],range(2,10))过滤所有子列表中,元素是’Iphone’ [示例代码有问题]
1
2
3
4
5
6
7def filter_shop(shop):
if shop:
return shop != 'Iphone'
else:
return False
shops = [['huawei', 'Iphone', 'xiaomi'], ['Iphone', 'meizu','vivo']]
filter(fitler_shop(shop)) for shop in shops过滤文件
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 os
#列出需要查找的目录的所有文件
files = os.listdir('D:\googleDownload')
a = filter(lambda file: file.endswith('gz'), files)
for i in a:
print(i)
------ 改正后代码
def filter_shop(shop):
if shop != 'Iphone':
return shop
else:
return False
shops = [['huawei', 'Iphone', 'xiaomi'], ['Iphone', 'meizu', 'vivo'], ['meizu']]
for items in shops:
for item2 in items:
a = filter_shop(item2)
# a = (a != "False" and a )
print(a)底层实现
1
2
3
4
5
6
7
8
9
10
11def filter1(func,seq):
# 建一个空序列,用于存储过滤后的元素
f_seq = []
#对序列中的每个元素进行迭代
for item in seq:
#如果为真的话
if func(item):
#满足条件者,则加入
f_seq.append(item)
# 返回过滤后的元素
return f_seq1
2
3
4
5
6
7
8
9
10
11
12
13代码测试
li = ['tiger', 'five', 'qf', 'f803']
def fi(test):
if test != 'tiger':
return test
a = filter1(fi, li)
for i in a:
print(i)
3、reduce
3.1、说明
reduce函数会对参数序列中元素进行累积。
在Python 3里,reduce()函数已经被从全局名字空间里移除了,它现在被放置在fucntools模块里 用的话要先引入。
3.2、语法
1 | reduce(function, sequence, initial=None) |
3.3、参数说明
function
处理序列的函数
sequence
序列对象
initial
可选参数第一次调用的参数
3.4、返回值
函数处理过的对象
3.5、备注
function有三个参数,
reduce依次从sequence中取一个元素,和上一次调用function的结果做参数再次调用function。
第一次调用function时,如果提供initial参数,会以sequence中的第一个元素和initial作为参数调用function,
否则会以序列sequence中的前两个元素做参数调用function
3.6、举个栗子
对字符串的处理
1
2
3value1 = reduce(lambda x, y: x + y,['hello', 'word'])
if __name__ == '__main__':
print(value1)两个参数的数字类型处理
1
2
3value2 = reduce(lambda x, y: x * y, [1, 2, 3, 4])
if __name__ == '__main__':
print(value2)func()函数不能为None,否则报错
1
2
3
4
5
6
7print(reduce(None,[1,2,3,4]))
"""
Traceback (most recent call last):
File "/Users/zhangwei/work/PycharmProjects/Demo/day05/src/lambda_reduce.py", line 12, in <module>
print(reduce(None,[1,2,3,4]) )
TypeError: 'NoneType' object is not callable
"""func(x,y)只能有两个参数,否则报错
1
2
3
4
5
6
7
8print(reduce(lambda x: x * 2, [1, 2, 3, 4], 10))
"""
Traceback (most recent call last):
File "/Users/zhangwei/work/PycharmProjects/Demo/day05/src/lambda_reduce.py", line 12, in <module>
print(reduce(lambda x: x * 2, [1, 2, 3, 4], 10))
TypeError: <lambda>() takes 1 positional argument but 2 were given
"""底层实现
1
2
3
4
5
6
7
8
9def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
value = next(it)
else:
value = initializer
for element in it:
value = function(value, element)
return value