永发信息网

请问这段Python代码如何用匿名函数简化?

答案:2  悬赏:60  手机版
解决时间 2021-02-09 16:35
  • 提问者网友:ミ烙印ゝ
  • 2021-02-09 13:18
这是原代码,是一个返回函数的例子,作用是让f1,f2,f3 = count(),f1(),f2(),f3()的输出结果都一样
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i))
return fs

我试了一下修改成这样:
def count():
def f(j):
return lambda j:j*j
fs = []
for i in range(1,4):
fs.append(f(i))
return fs
令f = count(),运行f()时,提示() missing 1 required positional argument: 'j'这样的错误信息
还试了一下这样:
def count():
fs = []
def f(j):
return lambda j=j:j*j
for i in range(1,4):
fs.append(f(i))
return fs
运行时,提示'list' object is not callable这样的错误信息

各位大神能不能告诉我应该怎样修改,指出我的两种修改方法错误的地方呢?
最佳答案
  • 五星知识达人网友:过活
  • 2021-02-09 14:25
楼主你好!
要解决这道题目并不难,只需要理解匿名lambda是如何使用的便可;
“lambda 表达式1:表达式2”其实就是定义了一个函数,传入表达式1的参数,按表达式2的形式返回,因此,该语句也就返回了一个函数对象,请看如下代码:
def demo(x):
    return x*x

lambda_demo = lambda x:x*x以上代码中demo函数和lambda_demo是等效的,都是可以调用的对象,传入一个参数,返回这个参数的平方。
那这题就不难解了,其实做的事情就是定义了两层:
1)第一层函数是传入一个参数,返回第二层定义的函数对象
2)第二层是不传入参数,返回第一层参数的平方
套用lambda的定义,便不难解出正确答案:
# -*- coding: utf-8 -*-
def count():
    '''这是原函数'''
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i))
    return fs

def edited_count():
    '''这是修改后的函数'''
    fs= []
    for i in range(1, 4):
        fs.append((lambda x:(lambda :x*x))(i))
    return fs

def evol_count():
    '''更加pythonic的写法'''
    return [(lambda x:(lambda :x*x))(i) for i in range(1,4)]

'''一行式写法'''
one_line_count = lambda :[(lambda x:(lambda :x*x))(i) for i in range(1,4)]

再分析一下楼主两段错误代码:
第一段的报错原因在于,楼主混淆了变量的有效空间,lambda中的变量只是形式,并不会对外部变量进行录入,所以在f函数中传入的j,并不会记录在lambda中,因此,在最后执行的时候,列表中的三个函数是第一段代码段中的demo函数,需要楼主传入一个参数,再返回你传入参数的平方。
第二段代码看代码逻辑应该是正确的,这个修改发生了什么呢?其实你定义的lambda函数形式变成了这样:
def demo(x=1):
    return x*x也就是变相的把变量的值给定义了,出错的原因应该是你在调用的时候很可能是以这样的形式调用:count()() 才导致了报错。
希望楼主能够深入理解lambda以及python的命名空间,今后遇到这样的题目便能迎刃而解了。
望采纳,谢谢!~
全部回答
  • 1楼网友:执傲
  • 2021-02-09 15:40
lambda函数一般是在函数式编程中使用的。通常学习的c/c++/java等等都是过程式编程,所以不常接触lambda函数。 其实这货在c++中已经有所运用了,如果对stl的迭代器比较熟悉的话,就会知道里头的foreach等函数,需要给一个函数,这对于c/c++这种古老的语言来说比较痛苦,一般是在主函数外再写一个函数,然后传入函数指针,看起来非常不直观。boosts用一些特殊的语法技巧实现了c++的lambda。 举个栗子,对于这样一个list l,求l中大于3的元素集合 l = [1, 2, 3, 4, 5] 对于过程式编程,通常会这么写l3 = []for i in l:if i 3:l3.append(i) 而对于函数式变成,只需要给filter函数一个判断函数就行了 def greater_than_3(x): return x 3 l3 = filter(greater_than_3, l) 由于这个判断函数非常简单,用def写起来太累赘了,所以用lambda来实现就非常简洁、易懂 l3 = filter(lambda x: x 3, l) 这是个很简单的例子,可以看出lambda的好处。lambda函数更常用在map和reduce两个函数中。 当然,lambda函数也不见得都好,它也可以被用得很复杂,比如这个问题 的答案,可以用python这样一句解决,这个lambda函数看起来那的确是挺辛苦的。
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯