回答
Python的itertools
page正好有此一powerset
配方:
def powerset(iterable):
"powerset([1,2,3]) -->() (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
輸出:
>>> list(powerset("abcd"))
[(), ('a',), ('b',), ('c',), ('d',), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd'), ('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'c', 'd'), ('b', 'c', 'd'), ('a', 'b', 'c', 'd')]
如果你不喜歡一開始是空的元組,你可以改變的range
聲明到range(1, len(s)+1)
以避免0長度的組合。
這是我能找到的最快速的答案,比較本頁上的一些其他解決方案使用Python的timeit模塊。但是,在某些情況下,如果需要修改生成的輸出(例如,連接字母以形成字符串),那麼使用生成器編寫自定義配方並構建所需的輸出(例如,將兩個字符串相加在一起)會更快。 – 2018-02-23 07:48:05
以下是powerset的更多代碼。這是從頭寫起:
>>> def powerset(s):
... x = len(s)
... for i in range(1 << x):
... print [s[j] for j in range(x) if (i & (1 << j))]
...
>>> powerset([4,5,6])
[]
[4]
[5]
[4, 5]
[6]
[4, 6]
[5, 6]
[4, 5, 6]
馬克Rushakoff的評論這裏是適用的:「如果你不喜歡一開始是空的元組,對」你可以改變的範圍內聲明的範圍(1,LEN (S)+1),以避免一個長度爲0的組合」,除了在我的情況下更改for i in range(1 << x)
到for i in range(1, 1 << x)
後來回到這幾年,我現在會寫這樣的:
def powerset(s):
x = len(s)
masks = [1 << i for i in range(x)]
for i in range(1 << x):
yield [ss for mask, ss in zip(masks, s) if i & mask]
然後測試代碼是這樣的,說:
print(list(powerset([4, 5, 6])))
使用yield
意味着你不需要計算一整塊內存中的所有結果。預先計算主環路外的掩模被認爲是一種有價值的優化。
這是一個有創意的答案。但是,我使用timeit對它進行了測量,並將其與Mark Rushakoff進行比較,發現它顯着較慢。爲了產生100次的16個項目的功率集,我的測量結果是0.55對15.6。 – 2018-02-23 07:40:35
如果你正在尋找一個快速的答案,我只是搜查谷歌「巨蟒發電機組」以及與此想出了:Python Power Set Generator
下面是在頁面的代碼複製粘貼:
def powerset(seq):
"""
Returns all the subsets of this set. This is a generator.
"""
if len(seq) <= 1:
yield seq
yield []
else:
for item in powerset(seq[1:]):
yield [seq[0]]+item
yield item
這可以像這樣使用:
l = [1, 2, 3, 4]
r = [x for x in powerset(l)]
現在r爲所有你想要的元素列表,並且可以進行排序並打印:
r.sort()
print r
[[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 4], [1, 3], [1, 3, 4], [1, 4], [2], [2, 3], [2, 3, 4], [2, 4], [3], [3, 4], [4]]
如果輸入的是空數組,則上述代碼將返回'[[] []]',以解決長度檢查情況下分開的情況 'if len(seq)== 0: yield [] elif len(seq)== 1: yield seq yield []' – 2017-10-18 18:32:44
作爲參考,我使用timeit測量了它(與Ayush的編輯),並將其與Mark Rushakoff的答案中的powerset配方進行了比較。在我的機器上,爲了產生100個項目的16個項目的powerset,這個算法花了1.36秒,而Rushakoff花了0.55。 – 2018-02-23 07:44:20
def powerset(lst):
return reduce(lambda result, x: result + [subset + [x] for subset in result],
lst, [[]])
我只是想提供最易於理解的解決方案,反碼高爾夫版本。
from itertools import combinations
l = ["x", "y", "z", ]
def powerset(items):
combo = []
for r in range(len(items) + 1):
#use a list to coerce a actual list from the combinations generator
combo.append(list(combinations(items,r)))
return combo
l_powerset = powerset(l)
for i, item in enumerate(l_powerset):
print "All sets of length ", i
print item
結果
所有套長度的0
[()]
所有套長度的1
[('x',), ('y',), ('z',)]
所有套長度的2
[('x', 'y'), ('x', 'z'), ('y', 'z')]
所有套長度3
[('x', 'y', 'z')]
的維基百科條目這是野生的,因爲沒有這些答案實際上提供了實際Python集的返回。這是一個混亂的實現,它將給出一個實際上是Python set
的powerset。
test_set = set(['yo', 'whatup', 'money'])
def powerset(base_set):
""" modified from pydoc's itertools recipe shown above"""
from itertools import chain, combinations
base_list = list(base_set)
combo_list = [ combinations(base_list, r) for r in range(len(base_set)+1) ]
powerset = set([])
for ll in combo_list:
list_of_frozensets = list(map(frozenset, map(list, ll)))
set_of_frozensets = set(list_of_frozensets)
powerset = powerset.union(set_of_frozensets)
return powerset
print powerset(test_set)
# >>> set([ frozenset(['money','whatup']), frozenset(['money','whatup','yo']),
# frozenset(['whatup']), frozenset(['whatup','yo']), frozenset(['yo']),
# frozenset(['money','yo']), frozenset(['money']), frozenset([]) ])
雖然我很想看到更好的實現。
def get_power_set(s):
power_set=[[]]
for elem in s:
# iterate over the sub sets so far
for sub_set in power_set:
# add a new subset consisting of the subset at hand added elem
power_set=power_set+[list(sub_set)+[elem]]
return power_set
例如:
get_power_set([1,2,3])
產量
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
在其管理的循環中修改循環變量('power_set')是一個非常有問題的做法。例如,假設你寫了這個而不是提出的變量修改代碼:'power_set + = [list(sub_set)+ [elem]]'。然後循環不會終止。 – hughdbrown 2016-05-25 05:24:52
這裏是我快速實現利用組合,但只使用內置插件。
def powerSet(array):
length = str(len(array))
formatter = '{:0' + length + 'b}'
combinations = []
for i in xrange(2**int(length)):
combinations.append(formatter.format(i))
sets = set()
currentSet = []
for combo in combinations:
for i,val in enumerate(combo):
if val=='1':
currentSet.append(array[i])
sets.add(tuple(sorted(currentSet)))
currentSet = []
return sets
有冪的改進:
def powerset(seq):
"""
Returns all the subsets of this set. This is a generator.
"""
if len(seq) <= 0:
yield []
else:
for item in powerset(seq[1:]):
yield [seq[0]]+item
yield item
我發現下面的算法非常簡單明瞭:
def get_powerset(some_list):
"""Returns all subsets of size 0 - len(some_list) for some_list"""
if len(some_list) == 0:
return [[]]
subsets = []
first_element = some_list[0]
remaining_list = some_list[1:]
# Strategy: get all the subsets of remaining_list. For each
# of those subsets, a full subset list will contain both
# the original subset as well as a version of the subset
# that contains first_element
for partial_subset in get_all_subsets(remaining_list):
subsets.append(partial_subset)
subsets.append(partial_subset[:] + [first_element])
return subsets
另一種方法可以產生冪是通過生成所有具有n
位的二進制數字。作爲一個功率設置n
數字的數量是2^n
。該算法的原理是元素可以存在或不存在於一個子集中,因爲二進制數字可以是一個或零,但不能同時存在。
def power_set(items):
N = len(items)
# enumerate the 2 ** N possible combinations
for i in range(2 ** N):
combo = []
for j in range(N):
# test bit jth of integer i
if (i >> j) % 2 == 1:
combo.append(items[j])
yield combo
我發現,當我正在MITX兩種算法:6.00.2x介紹計算思維和數據科學,我認爲這是最簡單的算法之一瞭解我所看到的。
"""
from https://docs.python.org/3.6/library/itertools.html
uses the module itertools
chaining together the two functions combinations() and chain() is faster
than iterating and generator functions in Python
Author: joltE
Date: 3/15/2017
"""
def powerset(iterable):
"powerset([1,2,3]) -->() (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
from itertools import chain, combinations
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
def AllCombo(items):
return [list(i) for i in powerset(items)]
測試臺
print(AllCombo([1, 3, 5, 7]))
print([list(i) for i in powerset([1, 3, 5, 7])])
冪()的作用就像一個發電機的功能,但是更有效,因爲僅使用內置函數鏈()以及它們的組合和itertools至()。 powerset()輸出元組,這可以轉換爲列表,就像在AllCombo中使用list()函數一樣。測試平臺中的兩個打印語句都輸出相同的數據。
- 1. 什麼是通過SNMP顯示浮點數的好方法?
- 2. 通過WAN打開大文件的好方法是什麼?
- 3. 通過方法調用什麼是好的Java設計?
- 4. 創建嵌套結構,更好的方法是什麼?
- 5. 通過Java中的方法組合類
- 6. 什麼是好的重疊組算法?
- 7. 寫好條件組合的好方法
- 8. 在Excel 2003中創建可變大小的組合的好方法是什麼?
- 9. 什麼是更好的方法
- 10. 什麼是更好的方法?
- 11. 什麼是定製Sylius的好方法?
- 12. 什麼是記錄最好的方法?
- 13. 什麼是最好的Ajax方法?
- 14. 調用notifyAll的好方法是什麼?
- 15. 什麼是管理Postfix的好方法?
- 16. Sort ObservableCollection - 什麼是最好的方法?
- 17. 什麼是更好的方法?
- 18. 什麼是循環API的好方法?
- 19. 什麼是實現run()的好方法?
- 20. 什麼是最好的方法有URL
- 21. 什麼是通過FTP部署PHP/MySQL站點的好方案?
- 22. 什麼是迭代通過一個numpy數組最快的方法
- 23. 什麼是耦合和分離鏈接類的好方法?
- 24. 合併之前清理數據的更好方法是什麼?
- 25. 什麼是使用Python混合RSS提要的好方法?
- 26. 用於一組大數據的好集合是什麼?
- 27. 重置深度嵌套集合的最佳方法是什麼?
- 28. 什麼是一些很好的方法來反轉嵌套散列?
- 29. 爲什麼順序不通過組合?
- 30. 什麼是全套的法律參數,我可以通過presentFeedDialogModallyWithSession
你的意思是像一個元素的權力集? – hughdbrown 2009-09-26 22:14:13
(是「一些奇怪的lambda的東西」的技術術語?) – 2009-09-26 22:43:08