将函数实现为Lambda

时间:2014-09-28 07:03:04

标签: python lambda

有没有办法将以下函数实现为lambda:

def z(s,f):
 for c in s:
  if c in f:f.remove(c)
  else:return 0
 return 1

我最大的麻烦是f.remove(c)

z=lambda s,f:f.remove(c) if c in f else 0 for c in s;1

上面的代码只是抱怨语法错误。

请注意,我并非将此用于任何严肃的目的,仅用于休闲码打高尔夫球。

3 个答案:

答案 0 :(得分:3)

等效lambda

lambda s, f: int(all(c in f and f.remove(c) is None for c in s))

这仅使用适当的字符对andallremove的惰性评估。

答案 1 :(得分:2)

可以把它写成一个lambda,但你真的,真的不应该。

首先,您必须将每个语句转换为表达式。这里有多个步骤,每个步骤都是个坏主意。

if c in f: f.remove(c)变为f.remove(c) if c else 0。在这样的表达式中使用仅被称为副作用的函数是非常不合理的,但这并不违法。我们只需要考虑f.remove(c)总是返回None这一事实,并选择我们可以放在另一个分支中的其他内容。

现在,这不会早日回归,因为那是不可能的;你不能在表达式中包含return语句或任何语句。我们稍后会再回过头来看。

接下来,for语句必须成为某种理解,在本例中为生成器表达式:(f.remove(c) if c in f else 0 for c in s)。请注意,我们将值None0放入迭代器中,即使我们实际上并不关心这些值,因此这是对误解的误解,但同样不是非法的。

现在我们可以使用all函数来处理“早期返回”:all(value is None for value in (f.remove(c) if c in f else 0 for c in s))。如果每个值都为True,则为None,但只要找到一个不是{因为c in f为假),它就会停止,并评估为{{1} }。我们可以通过调用False(或使用False0转换为True1转换为int,但为什么还要麻烦在这一点上试图成为Pythonic?)所以:

1 if foo else 0

当然这是对z = lambda s, f: int(all(value is None for value in (f.remove(c) if c in f else 0 for c in s)) 的误用,因为lambda的整个点是它给了我们一个可以在表达式中间定义的匿名函数;如果你想在一个语句中定义它并给它起一个名字,那么你使用lambda而不是lambda所做的就是混淆你的代码。

如果您愿意,可以将两个循环合并为一个,并进行各种其他更改,以便在您打算使用代码高尔夫时更加简洁。

答案 2 :(得分:0)

如果我们正在寻找愚蠢的想法,我想到了从表达式早期实际返回的方法。首先,我们需要一些可重复使用的脚手架:

class Return(Exception): pass

def throw(e): raise e

def early(f):
    try:
        return f()
    except Return as e:
        return e.args[0]

现在:

z = lambda s, f: early(lambda: [f.remove(c) if c in f else throw(Return(0)) 
                                for c in s])

如果PEP 463被接受,那么early函数将不再必需,内部lambda也不会:

z = lambda s, f: [f.remove(c) if c in f else throw(Return) 
                  for c in s] except Return: 0