Python匿名函数Lambda:想明白这些练习结果,Lambda才算懂了

Python的lambda样式相对其他语言比较简单。
lambda 不能出现=,不出现return,冒号是最后一个表达式,表达式计算的结果作为该匿名函数的返回值

>>> fn = lambda : 0
>>> fn
<function __main__.<lambda>()>
>>> def fn(x):
>>>     return x+1

改造为等价的lamda函数

>>> lambda x: x+1
<function __main__.<lambda>(x)>

调用lamda,加上括号:lamda的括号表示调用,不表示元组,元组是要在元素后面加逗号的。

>>> (lambda x: x+1)(1)
2
>>> (lambda *, x ,y:x+y,)[0](x=4,y=5) #当lambda函数被当做一个元组
9

与普通函数一样,如果有关键字参数,需要放在后面:

>>> (lambda x,y=2:x+y)(1)
3
>>> (lambda *, x ,y:x+y)(x=4,y=5)
9

如果将括号换成中括号,则报callable TypeError

# [lambda *, x ,y:x+y](x=4,y=5)
>>> [lambda *, x ,y:x+y]
[<function __main__.<lambda>(*, x, y)>]

如果将列表里的lambda拿出来就可以被调用callable了:

>>> [lambda *, x ,y:x+y][0]
<function __main__.<lambda>(*, x, y)>
>>> [lambda *, x ,y:x+y][0](x=4,y=5)
9
>>> ([lambda *, x ,y:x+y][0])
<function __main__.<lambda>(*, x, y)>

用lambda传多个参数

>>> [lambda *args: args][0](4,5,6)
(4, 5, 6)
>>> lambda *args: args
<function __main__.<lambda>(*args)>
>>> (lambda *, x, y:x+y,)[0](y =4 , x=5)
9
>>> (lambda *args, **kwargs:(args, kwargs))(1,2,3,x=1,y=2)
((1, 2, 3), {'x': 1, 'y': 2})
>>> (lambda *args: [ x for x in args])(4,5,6)
[4, 5, 6]
>>> (lambda *args: list(args))(4,5,6)
[4, 5, 6]
>>> (lambda *args: [args])(4,5,6)
[(4, 5, 6)]
>>> (lambda *args: {x +1 for x in args})(4,5,6)
{5, 6, 7}

思考一下下面的会返回什么

>>> (lambda *args : (x for x in args)) #这是一函数
<function __main__.<lambda>(*args)>
>>> (lambda *args : (x for x in args))(4,5) #这是一个生成器
<generator object <lambda>.<locals>.<genexpr> at 0x0000023C9923B570>
>>> g = (lambda *args : (x for x in args))(4,5) #这是一个生成器
>>> next(g)
4
>>> g = (lambda *args : [x for x in args])(4,5) #这是一个列表
>>> g
[4, 5]
>>> (lambda *args : [args])(4,5) #返回值元组,被进一步被作为了列表的一个元素
[(4, 5)]
>>> (lambda *args : list(args))(4,5) #对比
[4, 5]
>>> (lambda *args : {args})(4,5) #对比
{(4, 5)}
>>> (lambda *args:{x+1 for x in args})(4,5,6)
{5, 6, 7}
#  (lambda *args:{x+1 for x in args})(range(10))  # 对象不能与int相加
>>>  (lambda *args:{x for x in args})(range(10))
{range(0, 10)}
>>> range(10)
range(0, 10)

结合random函数、参数解构和列表解析式

进一步理解Python lambda匿名函数

>>> import random
>>> ret = (lambda *args: (x%3 for x in args))(*[i for i in range(100)])
>>> #结果是一个生成器,各次分别生成0,1,2
>>> ret
<generator object <lambda>.<locals>.<genexpr> at 0x0000023C9923BF68>
>>> next(ret)
0
>>> next(ret)
1
>>> next(ret)
2
>>> next(ret)
0
>>> import random
>>> ret = (lambda *args: {x%3 for x in args})(*[i for i in range(100)])
>>> #结果是集合,集合可以去重
>>> ret
{0, 1, 2}
>>> import random
>>> ret2 = (lambda *args: {x%3 for x in args})(*[random.randint(1,1000) for i in range(100)])
>>> next(ret2)
>>> next(ret2)
>>> next(ret2)
>>> next(ret2)
>>> next(ret2)
>>> import random
>>> ret3 = (lambda *args: {x%3 for x in args})(*[random.randint(1,1000) for i in range(100)])
>>> ret3
{0, 1, 2}

高阶函数使用lambda

####  用lambda模拟sorted
>>> sorted(["a",1,"b",2,"c",12],key = str)
[1, 12, 2, 'a', 'b', 'c']
>>> sorted(["a",1,"b",2,"c",12],key = lambda item: str(item) )
[1, 12, 2, 'a', 'b', 'c']
>>> sorted(["a",1,"b",2,"c",12], key = lambda item:int(item,16) if isinstance(item, str) else item)
[1, 2, 'a', 'b', 'c', 12]
#等价写法
>>> sorted(["a",1,"b",2,"c",12], key = lambda item:int(item,16) if type(item)==str else item)
[1, 2, 'a', 'b', 'c', 12]

defaultdict字典使用lambda

>>> from collections import defaultdict
>>> d = defaultdict(list) #defaultdict类就好像是一个dict,但是它是使用一个类型来初始化的:
>>> d[0].extend((1,2,3))
>>> d[2].extend((4,5,6))
>>> d
defaultdict(list, {0: [1, 2, 3], 2: [4, 5, 6]})
>>> from collections import defaultdict
>>> d = defaultdict(lambda :list()) #改造lambda版本 : (lambda:list())()
>>> d[0].extend((1,2,3))
>>> d[2].extend((4,5,6))
>>> d
defaultdict(<function __main__.<lambda>()>, {0: [1, 2, 3], 2: [4, 5, 6]})
>>> from collections import defaultdict
>>> d = defaultdict(lambda :[]) # 改造lambda版本2,无参调用后返回空列表
>>> d[0].extend((1,2,3))
>>> d
defaultdict(<function __main__.<lambda>()>, {0: [1, 2, 3]})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章