簡體   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]]]

我已經嘗試了上面的代碼,它只返回[[],[1],[2],[3]]

因此,我不小心嘗試了如下一條班輪退貨聲明:

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]

而且有效。 我不明白在return語句中使用for循環如何使此代碼起作用。 請幫助我了解它的工作原理,因為我嘗試在可視化工具上運行它,但我仍然不明白。

並且,如果可以的話,可以使我的第一個代碼正常工作而無需使用一個線性返回語句。

先進的百萬分率

第一種情況無法返回你的預期,因為結果return 里面的語句循環。 基本上,代碼將在for循環的第一次迭代中退出函數(僅累加第一個子集,然后返回結果並結束函數調用)...第二個示例對所有子集求和,然后返回結果。

第一種情況的問題是它在for循環中第一次返回。 對於第一個e,它返回然后退出循環。 要修復您的代碼:

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]]

我更喜歡列表理解版本。

除了關於代碼的問題之外,這是一種獲取所有子集列表的方法:

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

這是一個工作函數,用於返回任何給定序列的所有子集的列表:

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

...請注意,此lambda是遞歸定義的(就像在函數中一樣)。

同樣,對於n個元素,子集集的大小增長為2 ** n也毫無意義。 換句話說,對於一組10個元素,子集具有1024個元素。

考慮和建模的方式是考慮從0到2 ** n ...的所有二進制數...如果您枚舉所有這樣的位串並將每個位串視為要包括在其中的項的“掩碼”相應的子集,您將發現您涵蓋了從空集(0)到完整原始集(11111 ... 1111)的所有可能子集。

這樣做的一個含義是,您可以返回序列的“第n個”“子集”,而無需枚舉所有中間的“子集”(斜線引號,因為在數學上,一個集合是無序的;但是這種處理方式取決於將位字符串映射到序列。 ..在“集合”上有序處理)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM