简体   繁体   English

这两个Python子集递归函数代码有什么区别?

[英]What is the difference between these two codes of Python subset recursion function?

def all_subsets(s):
    if len(s) == 1: return [[], s]
    else:
        sets = all_subsets(s[:-1])
        for e in sets:
            return sets + [e + [s[-1]]]

I've tried the above code and it only returns [[], [1], [2], [3]] 我已经尝试了上面的代码,它只返回[[],[1],[2],[3]]

So I've accidentally tried the one liner return statement as below: 因此,我不小心尝试了如下一条班轮退货声明:

def all_subsets(s):
    if len(s) == 1: return [[], s]
    else:
        sets = all_subsets(s[:-1])
        return sets + [e + [s[-1]] for e in sets]

And it worked. 而且有效。 I can't understand how using for loop in the return statement makes this code work; 我不明白在return语句中使用for循环如何使此代码起作用。 PLEASE help me understand how it's working, because I've tried running it on the visualizer, and I still don't understand. 请帮助我了解它的工作原理,因为我尝试在可视化工具上运行它,但我仍然不明白。

AND if you can be so kind as to make my FIRST code work without using the one liner return statement, if it is possible. 并且,如果可以的话,可以使我的第一个代码正常工作而无需使用一个线性返回语句。

A MILLION GRATITUDES IN ADVANCE 先进的百万分率

The first case fails to return the result you expected because of the return statement inside the for loop. 第一种情况无法返回你的预期,因为结果return 里面的语句循环。 Basically the code will exit the function in the first iteration of the for loop (summing only the first subset and then returning the result and ending the function call)... The second example sums all the subsets and then returns the result. 基本上,代码将在for循环的第一次迭代中退出函数(仅累加第一个子集,然后返回结果并结束函数调用)...第二个示例对所有子集求和,然后返回结果。

The problem in your first case is that it returns the first time in the for loop. 第一种情况的问题是它在for循环中第一次返回。 For the first e, it returns and then gets out of the loop. 对于第一个e,它返回然后退出循环。 To fix your code: 要修复您的代码:

def all_subsets(s):
    if len(s) == 1: return [[], s]
    else:
        sets = all_subsets(s[:-1])
        returnset = []
        for e in sets:
            returnset.extend([e,e + [s[-1]]])
        return returnset

s= [1,2,3]
print all_subsets(s)

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

I would prefer the list comprehension version though. 我更喜欢列表理解版本。

Apart from the question about your code, here's a way to get a list of all subsets: 除了关于代码的问题之外,这是一种获取所有子集列表的方法:

(from: https://wiki.python.org/moin/Powerful%20Python%20One-Liners ) (摘自: https : //wiki.python.org/moin/Powerful%20Python%20One-Liners

Here's a working function to return a list of all subsets of any given sequence: 这是一个工作函数,用于返回任何给定序列的所有子集的列表:

#!/python
f = lambda l: reduce(lambda z, x: z + [y + [x] for y in z], l, [[]])

... notice that this lambda is defined recursively (just as in your functions). ...请注意,此lambda是递归定义的(就像在函数中一样)。

Also it's worth nothing that the size of the set of subsets grows as 2**n for n elements. 同样,对于n个元素,子集集的大小增长为2 ** n也毫无意义。 In other words for a set of 10 elements the set of subsets has 1024 elements. 换句话说,对于一组10个元素,子集具有1024个元素。

What way of thinking of this and modeling it is to consider the all of the binary numbers from 0 to 2**n ... if you enumerate all such bit strings and consider each to be a "mask" of which items to include in the corresponding subset then you'll find that you've covered all possible subsets from the empty set (0) through the full original set (11111...1111). 考虑和建模的方式是考虑从0到2 ** n ...的所有二进制数...如果您枚举所有这样的位串并将每个位串视为要包括在其中的项的“掩码”相应的子集,您将发现您涵盖了从空集(0)到完整原始集(11111 ... 1111)的所有可能子集。

One implication of this is that you can return the "nth" "subset" of a sequence without enumerating all the intervening "subsets" (scare quotes because, mathematically a set is unordered; but this handling depends on mapping bit strings to a sequence ... on the "set" being treated in an orderly). 这样做的一个含义是,您可以返回序列的“第n个”“子集”,而无需枚举所有中间的“子集”(斜线引号,因为在数学上,一个集合是无序的;但是这种处理方式取决于将位字符串映射到序列。 ..在“集合”上有序处理)。

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

相关问题 这两个代码有什么区别? - What's the difference between these two codes? 这两个代码有什么区别? - What's the difference between the two of the codes? python:if-in运算符。 这两个代码之间有区别吗? - python: if - in operator. Is there a difference between these two codes? 这两个代码之间的区别? - Difference between these two codes? 两个 Python 代码之间的详细区别是什么,它们都是为了在三个输入中找到最大数而编写的 - What is the detailed difference between two Python codes, both written to find the largest number among three inputs 计算文本中单词的两个代码有什么区别? - What is the difference between two codes that count words in a text? Django - 在 for 循环中注释 - 我的两个代码有什么区别 - Django - Annotate within for loop - what is the difference between my two codes 为什么Python和Cython中这两个代码之间存在巨大的性能差异? - Why there is a huge performance difference between these two codes in Python and Cython? 这两个python代码有什么区别? 为什么结果不同? - what's the difference between these 2 python codes? why different results? 这两个 python 代码有什么区别,为什么输出不一样? - what is the difference between these 2 python codes, and why the out put is not same?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM