简体   繁体   English

Python 问题 — lambda 版本的递归组合 function

[英]Python question — lambda version of a recursive combinations function

Okay so I have the following simple Python 3 function that does exactly what it's supposed to do:好的,所以我有以下简单的 Python 3 function 完全符合它的预期:

def comb(a):
    if len(a)==0:
        return[[]]
    else:
        p=[]
        for c in comb(a[1:]):
            p+=[c,c+a[:1]]      
        return p

which correctly produces正确产生

>>> comb([1,2,3])
[[], [1], [2], [2, 1], [3], [3, 1], [3, 2], [3, 2, 1]]

Motivated by nothing other than a desire to better my own understanding of recursive functions, I tried to see if I could turn this simple function into a lambda.除了希望更好地理解递归函数之外,我试图看看是否可以将这个简单的 function 变成 lambda。 First thing I tried was various versions of:我尝试的第一件事是各种版本:

comb=lambda a:[[]]if len(a)==0 else[[c,c+a[:1]]for c in comb(a[1:])]

Which, obviously, didn't work.显然,这没有用。 Then I took a step back and just tried to change the syntax of the original function like:然后我退后一步,只是尝试更改原始 function 的语法,例如:

def comb(a):
    return[[]]if len(a)==0 else[p for p in[[c,c+a[:1]]for c in comb(a[1:])]]

Which also doesn't work, like at all.这也不起作用,就像根本一样。 I tried all kinds of different arrangements but to no avail.我尝试了各种不同的安排,但无济于事。 Obviously the original function is the most useful and easiest to read, I'm only asking about this to better my own python understanding.显然,原来的 function 是最有用和最容易阅读的,我问这个只是为了更好地了解我自己的 python。 I'm normally pretty good at this game when recursion isn't involved so I'm just trying to understand what it is I'm missing here.当不涉及递归时,我通常很擅长这个游戏,所以我只是想了解我在这里缺少什么。

If your goal is to rewrite the function to lambda one-liner, you can do it using sum() for example:如果您的目标是将 function 重写为 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]))

Prints:印刷:

[[], [1], [2], [2, 1], [3], [3, 1], [3, 2], [3, 2, 1]]

NOTE: The above solution is not very readable.注意:上面的解决方案不是很可读。 The classic function is better.经典的function更好。


Thanks @Chris_Rands, solution with itertools.chain :感谢@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:]))]

Your problem is with the list comprehension.您的问题在于列表理解。

[[c,c+a[:1]]for c in l] is a list of length len(l) whose elements are lists are with 2 elements. [[c,c+a[:1]]for c in l]是一个长度为len(l)的列表,其元素是具有 2 个元素的列表。 What you want is a list of length 2*len(l) , which is the flattened version of this.你想要的是一个长度为2*len(l)的列表,这是它的扁平化版本。

comb=lambda a:[[]]if len(a)==0 else[c+a[:1]for c in comb(a[1:])] + comb(a[1:])

Works but can probably be improved because it makes 2 calls to comb each time, when only 1 is needed.有效,但可能可以改进,因为每次只需要 1 次时,它都会调用 2 次梳子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM