将lambda转换为Python中的普通函数
在我试图理解如何使用lambda表达式的时候,我看到一个回复,里面说用lambda能做的事情,用普通函数也都能做到。
我一直在努力尝试在Python中调用一个函数自己去执行,虽然我不是专家,但我在学习中遇到了一些需要用递归函数的情况,这种函数需要多次调用才能得到特定的答案。
有一个人用lambda函数来解决这个问题,我试着去理解,但没成功。所以我想,如果用普通函数来实现这个功能,可能会更容易理解lambda的用法。
我们以这个句子为例:
print"\n".join(" ".join([(lambda f:(lambda x:f(lambda*r:x(x)(*r)))(lambda x:f(lambda*r:x(x)(*r))))(lambda f:lambda q,n:len(q)<=n and q or f(q[len(q)/2:],n)+f(q[:len(q)/2],n))(k,z+1)for z,k in enumerate(i[:-1].split())]) for i in list(s)[1:])
这个问题在Facebook的黑客杯中被使用过,我没能解决这个问题,因为我在循环中迷失了。
这个句子包含几个单词,比如说“Stackoverflow rocks and it is great”。
Facebook中的问题描述是:
你拦截了一系列用一种有趣又愚蠢的方法加密的传输信息,你已经成功解密了这些信息。消息只包含空格和小写字母,且加密方式如下:对于句子中的每个单词,第i个单词(从1开始计数)会被替换成通过以下递归操作f(word, i)生成的单词:
如果单词的长度小于或等于i, 就返回这个单词。 否则,返回f(单词的右半部分, i) + f(单词的左半部分, i)。
如果单词长度是奇数,则右边的部分会更长。你决定和发送消息的人开个玩笑,自己也用他们的加密风格发送消息。
输入 你的输入将以一个整数N开始,接着是换行符,然后是N个测试用例。每个用例由一个未加密的句子组成,句子只包含空格和小写字母,且用例之间用换行分隔。句子中不会有前导或尾随空格,且相邻字符之间最多只有1个空格。
输出 对于每个用例,输出加密后的句子内容,并用换行分隔。你可以忽略传统的大小写规则,全部使用小写字母。
约束条件 5 ≤ N ≤ 25 句子最多包含100个字符。
1 个回答
Python中的lambda表达式其实就是一种语法上的简化。普通的函数也能做同样的事情,比如闭包,因为你可以在一个函数里面定义另一个函数,这和lambda的做法是一样的。
def some_func():
some_expr_using(lambda args: 42)
# becomes:
def some_func():
def unique_name(args):
return 42
some_expr_using(unique_name)
不过,当你查看lambda对象时,它的名字会显示为“<lambda>”,而不是像上面那样的unique_name,其他一些细节也是关于源代码的书写方式,而不是它的实际行为。
你的代码可以写成:
def y(f):
def a(x):
def b(*r):
return x(x)(*r)
return f(b)
return a(a)
def fx(f):
def x(q, n):
# changed "a and b or c": different semantics if b can be falsy
if len(q) <= n:
return q
else:
return f(q[len(q) / 2:], n) + f(q[:len(q) / 2], n)
return x
print "\n".join(
" ".join(y(fx)(k, z + 1) for z, k in enumerate(i[:-1].split()))
for i in list(s)[1:])
(但这得看我翻译得对不对,最好再检查一下。:P)
这段代码是一个不动点组合子的例子,我对这个概念了解得不多,想给它起个更好的名字也很难,因为我不知道更多的上下文(我没有尝试去理解实际的问题陈述)。它可以被展开成一个递归函数,这个函数可以直接通过名字调用自己。