![](/img/trans.png)
[英]find difference between lists and append difference to lists, but for 40 different lists - python
[英]Powerset algorithm in Python: difference between + and append on lists
我正在解決 Python 中的 powerset 問題。
集合 S 的冪集 P(S) 是 S 的所有子集的集合。 例如,如果S = {a, b, c}
那么P(s) = {{}, {a}, {b}, {c}, {a,b}, {a, c}, {b, c}, {a, b, c}}
。
這個解決方案工作得很好:
def powerset(array):
powerset = [[]]
for num in array:
for i in range(len(powerset)):
curr_subset = powerset[i]
powerset.append(curr_subset + [num])
return powerset
但是,此解決方案不會:
def powerset(array):
powerset = [[]]
for num in array:
for i in range(len(powerset)):
curr_subset = powerset[i]
curr_subset.append(num)
powerset.append(curr_subset)
return powerset
它似乎在每個 powerset.append 操作上覆蓋了 powerset 中的每個數組。 對於[1, 2, 3]
的輸入,我最終得到的返回值為:
[[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3]]
知道我在這里不完全理解嗎?
您的算法的問題在於列表是可變的,並且您正在創建一個包含對同一列表的引用的列表。 任何時候您附加到其中之一,您就是附加到所有這些,因為只有其中之一。 它們都是相同的列表,您只是有多個參考。
想象一下,有一份包含 10 個某人電話號碼副本的列表; 如果你撥打第一個電話號碼並要求他們戴上帽子,那么當你撥打第二個電話號碼時,另一端的人已經戴上了帽子,因為它是同一個人。 如果您呼叫每個號碼並每次都說“戴上帽子”,那么您最終會得到一個包含 10 個電話號碼的列表,其中包含一個戴 10 個帽子的人的電話號碼,而實際上您需要 10 個戴一頂帽子的人的電話號碼。
設計這種算法最簡單的方法就是完全避免變異; 使用元組而不是列表。 這樣,每次向元組添加另一個元素時,您都是在創建一個新元組,而不是更改現有元組。
請注意,這與您使用curr_subset + [num]
第一個解決方案非常相似; +
操作創建一個新列表,不像append
改變現有列表的狀態。
def powerset(array):
# a list containing an empty tuple
powerset = [()]
for num in array:
for i in range(len(powerset)):
curr_subset = powerset[i]
# append one more number to the tuple
curr_subset += (num,)
powerset.append(curr_subset)
return powerset
例子:
>>> powerset([1, 2, 3])
[(), (1,), (2,), (1, 2), (3,), (1, 3), (2, 3), (1, 2, 3)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.