好,所以我有以下简单的Python 3函数,可以完成应有的功能:
def comb(a):
if len(a)==0:
return[[]]
else:
p=[]
for c in comb(a[1:]):
p+=[c,c+a[:1]]
return p
正确产生
>>> comb([1,2,3])
[[], [1], [2], [2, 1], [3], [3, 1], [3, 2], [3, 2, 1]]
出于对更好地了解递归函数的渴望,我试图看看是否可以将这个简单的函数转换为lambda。我首先尝试的是以下版本的各种版本:
comb=lambda a:[[]]if len(a)==0 else[[c,c+a[:1]]for c in comb(a[1:])]
显然,这没有用。然后我退后一步,尝试更改原始函数的语法,例如:
def comb(a):
return[[]]if len(a)==0 else[p for p in[[c,c+a[:1]]for c in comb(a[1:])]]
这也根本不起作用。我尝试了各种不同的安排,但无济于事。显然,原始函数是最有用和最容易阅读的,我只是在问这个问题,以更好地了解自己的python。在不涉及递归的情况下,我通常会很擅长这款游戏,所以我只是想了解我在这里缺少的内容。
如果您的目标是将函数重写为lambda一线式,则可以使用sum()
来实现,例如:
comb = lambda a: [[]] if len(a)==0 else sum(([c,c+a[:1]] for c in comb(a[1:])), [])
print(comb([1, 2, 3]))
打印:
[[], [1], [2], [2, 1], [3], [3, 1], [3, 2], [3, 2, 1]]
注意:上面的解决方案不是很可读。经典功能更好。
感谢@Chris_Rands,使用itertools.chain
解决方案:
from itertools import chain
comb = lambda a: [[]] if len(a)==0 else [*chain.from_iterable([c,c+a[:1]] for c in comb(a[1:]))]
您的问题在于列表理解。
[[c,c+a[:1]]for c in l]
是长度为len(l)
的列表,其元素是具有2个元素的列表。您需要的是长度为2*len(l)
的列表,这是此值的扁平版本。
comb=lambda a:[[]]if len(a)==0 else[c+a[:1]for c in comb(a[1:])] + comb(a[1:])
有效,但可能会得到改进,因为每次只需要1个时,它都会进行2次调用以进行梳理。