lambda易错

def num():
    return [lambda x:i*x for i in range(4)]
print('这是num(): ',list(num()))
print([m(2) for m in num()])
for  i in num():
    print('每一个i:',i)
输出:
这是num():  [<function num.<locals>.<listcomp>.<lambda> at 0x00000000029759D8>, <function num.<locals>.<listcomp>.<lambda> at 0x0000000002975A60>, <function num.<locals>.<listcomp>.<lambda> at 0x0000000002975AE8>, <function num.<locals>.<listcomp>.<lambda> at 0x0000000002975B70>]
[6, 6, 6, 6]  # 每一个m(2)的值
<function num.<locals>.<listcomp>.<lambda> at 0x0000000002975BF8>
<function num.<locals>.<listcomp>.<lambda> at 0x0000000002975AE8>
<function num.<locals>.<listcomp>.<lambda> at 0x0000000002975B70>
<function num.<locals>.<listcomp>.<lambda> at 0x0000000002975950>

字典去重之后按原来的顺序重新排

list0=['b','c', 'd','b','c','a','a']
print(sorted(set(list0),key=list0.index)) # sorted output

面试易错lambda

# 面试易错的循环闭包lambda函数  闭包的相关知识 及闭包的后期绑定
def testfun():
    temp = [lambda x: i*x for i in range(4)]
    return temp
print(testfun())
for everylambda in testfun():
    print(everylambda(2))   #结果是 6,6,6,6
# 原因: python的闭包的后期绑定导致的 late binding,这意味着在闭包中的变量实在内部函数被调用的时候被查找.
# 所以结果是:当任何testfun()返回的函数被调用时,i的值在他被调用时的周围作用域中查找,到那时 ,
# 无论哪个返回的函数被调用,for循环都已经完成了 # i最后的值是3,因此,每个返回的函数testfun()的值都是3

改进方法一:

# 改正方法一:创建一个闭包,通过使用默认参数立即绑定他的参数
def testfun1():
    # return [lambda x: i * x for i in range(4)]
    return  [lambda x ,i = i : i*x  for i in range(4)]

for everylambda1 in testfun1():
    print(everylambda1(2),'你妹的')
输出 0,2,4,6

原版拆分

def func():
    fs = []
    for i in range(3):
        print('进入lam前i的值:', i)
        def lam(x):
            print('进入lam后i的值:', i)
            return x * i
        fs.append(lam)
    return fs
F = func()
print('009',F,type(F))

# 将x的值传入
for f in F:
    print(f(2))

print('这是---------------------------------------')
def func():
    fs = []
    for i in range(3):
        def lam(x, i=i):
            print('这是i',i)
            return x * i
        fs.append(lam)
    return fs
F = func()
for f in F:
    print('10',f(3))

输出:
进入lam前i的值: 0
进入lam前i的值: 1
进入lam前i的值: 2
009 [<function func.<locals>.lam at 0x0000000002876378>, <function func.<locals>.lam at 0x0000000009FF4620>, <function func.<locals>.lam at 0x0000000009FF46A8>] <class 'list'>
进入lam后i的值: 2
4
进入lam后i的值: 2
4
进入lam后i的值: 2
4
这是-------------
这是i 0
10 0
这是i 1
10 3
这是i 2
10 6

改正方法二:使用functools.partial函数,把函数的某些参数(不管有没有默认值)给固定起来(也就是相当与设置默认值)

from functools import partial
from operator import  mul
def  testfun2():
    return [partial(mul,i)for i in range(4)]
for everylambda2 in testfun2():
    print(everylambda2(2))
输出 0,2,4,6

def multipliers():
    return [partial(mul, i) for i in range(4)]
print('解决方式二',[m(2) for m in multipliers()])     #[0, 2, 4, 6]

改正方法三:优雅的写法,直接用生成器

def testfun3():
    return (lambda x:i*x for i in range(4))
for everylambda3 in testfun3():
    print(everylambda3(2))
输出 0,2,4,6

改正方法四:利用yield的惰性求值的思想

def testfun4():
    for i in range(4):
        yield lambda x : i*x

def multipliers1(x):
    for i in range(4):
        yield i*x
print('解决方式1.1',[m for m in multipliers1(2)])     #[0, 2, 4, 6]

for everylambda4 in testfun4():
print(everylambda4(2),'你好啊')

posted @ 2021-04-15 22:31  ty1539  阅读(138)  评论(0编辑  收藏  举报