Генерировать все подмножества размера k (содержащие k элементов) в Python

у меня есть набор значений и я хотел бы создать список всех подмножеств, содержащих 2 элемента.

например, исходный набор ([1,2,3]) имеет следующие 2-элементные подмножества:

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

есть ли способ сделать это в Python?

3 ответов


кажется, вы хотите itertools.combinations:

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

Если вы хотите наборы, вам придется явно преобразовывать их.

>>> s = set((1, 2, 3))
>>> map(set, itertools.combinations(s, 2))
[set([1, 2]), set([1, 3]), set([2, 3])]

это подмножество сила of {1, 2, 3} (или любой другой набор), содержащий все два элемента набора.

посмотреть Python itertools документация и поиск по термину "множество" для общего ответа на эту проблему.


просто чтобы дать другую перспективу, я искал способ повторить все подмножество размера 2 {1.....N}, поэтому я поставил 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

поэтому, я думаю, вы не всегда должны превращаться в общее решение.... Если вы заранее знаете размер подмножества, которое хотите, более эффективно использовать итерации для циклов.

Также обратите внимание, что вы не должны перебирать list(itertools.combinations(lst, 2)) так как этот шаг создает список (и намного медленнее, чем с помощью генератора сам.)