簡體   English   中英

在 Python 中生成所有大小為 k(包含 k 個元素)的子集

[英]Generate all subsets of size k (containing k elements) in Python

我有一組值,想創建包含 2 個元素的所有子集的列表。

例如,源集([1,2,3])具有以下 2 元素子集:

set([1,2]), set([1,3]), set([2,3])

有沒有辦法在 python 中做到這一點?

好像你想要itertools.combinations

>>> list(itertools.combinations((1, 2, 3), 2))
[(1, 2), (1, 3), (2, 3)]

如果你想要套裝,你必須明確地轉換它們。 如果您不介意迭代而不是列表,並且您使用的是Python 3,則可以使用map

>>> s = set((1, 2, 3))
>>> map(set, itertools.combinations(s, 2))
<map object at 0x10cdc26d8>

要一次查看所有結果,可以將map的輸出傳遞給list (在Python 2中, map的輸出自動為列表。)

>>> list(map(set, itertools.combinations(s, 2)))
[{1, 2}, {1, 3}, {2, 3}]

但是,如果你知道你需要一個列表,那么列表理解會略微好一些(h / t Jacob Bowyer ):

>>> [set(i) for i in itertools.combinations(s, 2)]
[{1, 2}, {1, 3}, {2, 3}]

這是包含所有兩元素集的{1, 2, 3} (或任何集合)的冪集的子集。

請參閱Python itertools文檔並搜索術語“powerset”以獲得此問題的一般答案。

為了給出另一個視角,我尋找一種方法來迭代{1.....N}所有2的子集,所以我將itertools.combinations置於測試中:

import itertools
from time import time


N = 7000
lst = [i for i in xrange(N)]

st = time()
c1 = 0
for x in itertools.combinations(lst, 2):
    c1 += 1
print "combinations: %f" % (time()-st)

st = time()
c2=0
for x in xrange(N):
    for y in xrange(x):
        c2 += 1
print "double loop: %f" % (time()-st)
print "c1=%d,c2=%d" % (c1,c2)

# prints:
#combinations: 4.247000
#double loop: 3.479000
# c1=24496500,c2=24496500

所以我想你不應該總是變成一般的解決方案......如果事先知道你想要的子集的大小,那么使用for循環迭代應該更有效率。

另請注意,您不應迭代list(itertools.combinations(lst, 2))因為此移動會創建列表(並且比使用生成器本身要慢得多)。

簡單的 PYTHON3 解決方案(給定大小數組中的排列)

def combinations(arr, n,k): 
    for i in range(n):
        for j in range(i+k-1,n):
            temp = arr[i:i+k-1]
            temp.append(arr[j])
            print(temp)
arr = [1,2,3,4,5,6]
k = 3
# All combinations subset with size k
print(combinations(arr,len(arr),k))

# OUTPUT
[1, 2, 3]
[1, 2, 4]
[1, 2, 5]
[1, 2, 6]
[2, 3, 4]
[2, 3, 5]
[2, 3, 6]
[3, 4, 5]
[3, 4, 6]
[4, 5, 6]

暫無
暫無

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

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