有没有办法将以下函数实现为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
上面的代码只是抱怨语法错误。
请注意,我并非将此用于任何严肃的目的,仅用于休闲码打高尔夫球。
答案 0 :(得分:3)
等效lambda
:
lambda s, f: int(all(c in f and f.remove(c) is None for c in s))
这仅使用适当的字符对and
和all
到remove
的惰性评估。
答案 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)
。请注意,我们将值None
和0
放入迭代器中,即使我们实际上并不关心这些值,因此这是对误解的误解,但同样不是非法的。
现在我们可以使用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
(或使用False
将0
转换为True
和1
转换为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