Учитывая набор
{0, 1, 2, 3}
Как я могу произвести подмножества:
[set(),
{0},
{1},
{2},
{3},
{0, 1},
{0, 2},
{0, 3},
{1, 2},
{1, 3},
{2, 3},
{0, 1, 2},
{0, 1, 3},
{0, 2, 3},
{1, 2, 3},
{0, 1, 2, 3}]
На itertools
странице Python есть точный powerset
рецепт для этого:
from itertools import chain, combinations
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)
чтобы избежать комбинации нулевой длины.
s = list(iterable)
нужен?__len__
реализации; попробуйтеpowerset((n for n in range(3)))
без переноса списка.powerset(range(3))
будет нормально работать даже безs = list(iterable)
.Вот еще код для набора мощности. Это написано с нуля:
>>> 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]
Комментарий Марка Рушакова применим здесь: «Если вам не нравится этот пустой кортеж в начале, on.», Вы можете просто изменить оператор диапазона на range (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
означает, что вам не нужно вычислять все результаты в одном фрагменте памяти. Предполагается, что предварительный расчет масок вне основного цикла является стоящей оптимизацией.источник
Если вы ищете быстрый ответ, я просто искал "python power set" в Google и нашел следующее: 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 []
def powerset(lst): return reduce(lambda result, x: result + [subset + [x] for subset in result], lst, [[]])
источник
Есть доработка powerset:
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
источник
TL; DR (перейти непосредственно к упрощению)
Я знаю, что ранее уже добавлял ответ, но мне очень нравится моя новая реализация. Я беру набор в качестве ввода, но на самом деле он может быть любым итеративным, и я возвращаю набор наборов, который является набором мощности ввода. Мне нравится этот подход, потому что он больше соответствует математическому определению набора мощности ( набора всех подмножеств ).
def power_set(A): """A is an iterable (list, tuple, set, str, etc) returns a set which is the power set of A.""" length = len(A) l = [a for a in A] ps = set() for i in range(2 ** length): selector = f'{i:0{length}b}' subset = {l[j] for j, bit in enumerate(selector) if bit == '1'} ps.add(frozenset(subset)) return ps
Если вам нужен именно тот результат, который вы опубликовали в своем ответе, используйте это:
>>> [set(s) for s in power_set({1, 2, 3, 4})] [{3, 4}, {2}, {1, 4}, {2, 3, 4}, {2, 3}, {1, 2, 4}, {1, 2}, {1, 2, 3}, {3}, {2, 4}, {1}, {1, 2, 3, 4}, set(), {1, 3}, {1, 3, 4}, {4}]
Объяснение
Известно, что количество элементов силового набора такое
2 ** len(A)
, чтобы хорошо было видно вfor
контуре.Мне нужно преобразовать входные данные (в идеале набор) в список, потому что набор представляет собой структуру данных из уникальных неупорядоченных элементов, и порядок будет иметь решающее значение для создания подмножеств.
selector
является ключевым в этом алгоритме. Обратите внимание, что онselector
имеет ту же длину, что и входной набор, и для этого используется f-строка с отступом. По сути, это позволяет мне выбирать элементы, которые будут добавляться к каждому подмножеству во время каждой итерации. Скажем, входной набор состоит из 3 элементов{0, 1, 2}
, поэтому селектор будет принимать значения от 0 до 7 (включительно), которые в двоичном формате:000 # 0 001 # 1 010 # 2 011 # 3 100 # 4 101 # 5 110 # 6 111 # 7
Таким образом, каждый бит может служить индикатором того, нужно ли добавлять элемент исходного набора или нет. Посмотрите на двоичные числа и просто подумайте о каждом числе как об элементе супернабора, что
1
означает, чтоj
должен быть добавлен элемент по индексу , и0
означает, что этот элемент не следует добавлять.Я использую понимание набора для создания подмножества на каждой итерации, и я конвертирую это подмножество в,
frozenset
чтобы добавить его вps
(набор мощности). В противном случае я не смогу добавить его, потому что набор в Python состоит только из неизменяемых объектов.Упрощение
Вы можете упростить код, используя некоторые понимания Python, чтобы избавиться от этих циклов for. Вы также можете использовать,
zip
чтобы избежать использованияj
индекса, и код будет следующим:def power_set(A): length = len(A) return { frozenset({e for e, b in zip(A, f'{i:{length}b}') if b == '1'}) for i in range(2 ** length) }
Вот и все. Что мне нравится в этом алгоритме, так это то, что он более ясный и интуитивно понятный, чем другие, потому что он выглядит волшебно, на что можно положиться,
itertools
даже если он работает так, как ожидалось.источник
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]]
. Тогда цикл не прекращается.Я нашел следующий алгоритм очень понятным и простым:
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_powerset(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 Introduction to Computational Thinking and Data Science, и считаю, что это один из самых простых для понимания алгоритмов, которые я видел.
источник
Я просто хотел предложить наиболее понятное решение - версию против кодового гольфа.
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')]
Для получения дополнительной информации см. Документацию itertools , а также статью в Википедии о наборах мощности
источник
Просто быстрое освежение питания!
Вот еще один способ найти набор мощности:
def power_set(input): # returns a list of all subsets of the list a if (len(input) == 0): return [[]] else: main_subset = [ ] for small_subset in power_set(input[1:]): main_subset += [small_subset] main_subset += [[input[0]] + small_subset] return main_subset print(power_set([0,1,2,3]))
полный кредит на источник
источник
Это можно сделать очень естественно с помощью
itertools.product
:import itertools def powerset(l): for sl in itertools.product(*[[[], [i]] for i in l]): yield {j for i in sl for j in i}
источник
Простым способом было бы использовать внутреннее представление целых чисел в арифметике с дополнением до 2.
Двоичное представление целых чисел выглядит как {000, 001, 010, 011, 100, 101, 110, 111} для чисел в диапазоне от 0 до 7. Для целочисленного значения счетчика, считая 1 включением соответствующего элемента в коллекцию и '0' в качестве исключения мы можем создавать подмножества на основе последовательности подсчета. Числа должны быть сгенерированы от
0
до,pow(2,n) -1
где n - длина массива, то есть количество битов в двоичном представлении.Простую функцию генератора подмножеств, основанную на ней, можно записать, как показано ниже. Это в основном полагается
def subsets(array): if not array: return else: length = len(array) for max_int in range(0x1 << length): subset = [] for i in range(length): if max_int & (0x1 << i): subset.append(array[i]) yield subset
а затем его можно использовать как
def get_subsets(array): powerset = [] for i in subsets(array): powerser.append(i) return powerset
Тестирование
Добавление следующего в локальный файл
if __name__ == '__main__': sample = ['b', 'd', 'f'] for i in range(len(sample)): print "Subsets for " , sample[i:], " are ", get_subsets(sample[i:])
дает следующий вывод
Subsets for ['b', 'd', 'f'] are [[], ['b'], ['d'], ['b', 'd'], ['f'], ['b', 'f'], ['d', 'f'], ['b', 'd', 'f']] Subsets for ['d', 'f'] are [[], ['d'], ['f'], ['d', 'f']] Subsets for ['f'] are [[], ['f']]
источник
С пустым набором, который является частью всех подмножеств, вы можете использовать:
def subsets(iterable): for n in range(len(iterable) + 1): yield from combinations(iterable, n)
источник
Почти во всех этих ответах используется
list
вместоset
, что для меня показалось немного читерским. Итак, из любопытства я попытался сделать простую версию действительно наset
и обобщить для других "новичков в Python".Я обнаружил, что при работе с реализацией набора Python есть пара странностей . Основным сюрпризом для меня стало обращение с пустыми наборами. Это контрастирует с реализацией Ruby Set , где я могу просто сделать
Set[Set[]]
и получитьSet
один пустойSet
, поэтому сначала я нашел это немного запутанным.Для обзора, работая
powerset
сset
s, я столкнулся с двумя проблемами:set()
принимает итерацию, поэтомуset(set())
вернется,set()
потому что итерируемый пустой набор пуст (да, я думаю :))set({set()})
иset.add(set)
не будет работать, потому чтоset()
не хешируетсяЧтобы решить обе проблемы, я использовал
frozenset()
, что означает, что я не совсем получаю то, что хочу (буквально шрифтset
), но использую общееset
взаимодействие.def powerset(original_set): # below gives us a set with one empty set in it ps = set({frozenset()}) for member in original_set: subset = set() for m in ps: # to be added into subset, needs to be # frozenset.union(set) so it's hashable subset.add(m.union(set([member])) ps = ps.union(subset) return ps
Ниже мы получаем
frozenset
правильные 2² (16) с на выходе:In [1]: powerset(set([1,2,3,4])) Out[2]: {frozenset(), frozenset({3, 4}), frozenset({2}), frozenset({1, 4}), frozenset({3}), frozenset({2, 3}), frozenset({2, 3, 4}), frozenset({1, 2}), frozenset({2, 4}), frozenset({1}), frozenset({1, 2, 4}), frozenset({1, 3}), frozenset({1, 2, 3}), frozenset({4}), frozenset({1, 3, 4}), frozenset({1, 2, 3, 4})}
Поскольку в Python нет возможности иметь a
set
ofset
s, если вы хотите превратить этиfrozenset
s вset
s, вам придется отобразить их обратно вlist
(list(map(set, powerset(set([1,2,3,4]))))
) или изменить приведенное выше.источник
Возможно, вопрос устаревает, но я надеюсь, что мой код кому-то поможет.
def powSet(set): if len(set) == 0: return [[]] return addtoAll(set[0],powSet(set[1:])) + powSet(set[1:]) def addtoAll(e, set): for c in set: c.append(e) return set
источник
Используйте функцию
powerset()
из пакетаmore_itertools
.>>> list(powerset([1, 2, 3])) [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
Если вам нужны наборы, используйте:
источник
Получение всех подмножеств с помощью рекурсии. Сумасшедший однострочный
from typing import List def subsets(xs: list) -> List[list]: return subsets(xs[1:]) + [x + [xs[0]] for x in subsets(xs[1:])] if xs else [[]]
На основе решения Haskell
источник
NameError: name 'List' is not defined
List
импортdef findsubsets(s, n): return list(itertools.combinations(s, n)) def allsubsets(s) : a = [] for x in range(1,len(s)+1): a.append(map(set,findsubsets(s,x))) return a
источник
Сделать это можно так:
def powerset(x): m=[] if not x: m.append(x) else: A = x[0] B = x[1:] for z in powerset(B): m.append(z) r = [A] + z m.append(r) return m print(powerset([1, 2, 3, 4]))
Выход:
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3], [4], [1, 4], [2, 4], [1, 2, 4], [3, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4]]
источник
Я знаю это слишком поздно
Уже есть много других решений, но все же ...
def power_set(lst): pw_set = [[]] for i in range(0,len(lst)): for j in range(0,len(pw_set)): ele = pw_set[j].copy() ele = ele + [lst[i]] pw_set = pw_set + [ele] return pw_set
источник
Это дико, потому что ни один из этих ответов на самом деле не возвращает фактический набор Python. Вот запутанная реализация, которая даст набор мощности, который на самом деле является Python
set
.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([]) ])
Однако мне бы хотелось увидеть лучшую реализацию.
источник
[*map(set, chain.from_iterable(combinations(s, r) for r in range(len(s)+1)))]
; функция arg ofmap
может быть,frozenset
если хотите.Вот моя быстрая реализация с использованием комбинаций, но с использованием только встроенных модулей.
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
источник
Все подмножества в диапазоне n установлены:
n = int(input()) l = [i for i in range (1, n + 1)] for number in range(2 ** n) : binary = bin(number)[: 1 : -1] subset = [l[i] for i in range(len(binary)) if binary[i] == "1"] print(set(sorted(subset)) if number > 0 else "{}")
источник
import math def printPowerSet(set,set_size): pow_set_size =int(math.pow(2, set_size)) for counter in range(pow_set_size): for j in range(set_size): if((counter & (1 << j)) > 0): print(set[j], end = "") print("") set = ['a', 'b', 'c'] printPowerSet(set,3)
источник
Вариант вопроса - это упражнение, которое я вижу в книге «Открытие компьютерных наук: междисциплинарные проблемы, принципы и программирование на Python. Издание 2015 года». В этом упражнении 10.2.11 входом является просто целое число, а выходом должны быть наборы мощности. Вот мое рекурсивное решение (не использующее ничего, кроме базового python3)
def powerSetR(n): assert n >= 0 if n == 0: return [[]] else: input_set = list(range(1, n+1)) # [1,2,...n] main_subset = [ ] for small_subset in powerSetR(n-1): main_subset += [small_subset] main_subset += [ [input_set[-1]] + small_subset] return main_subset superset = powerSetR(4) print(superset) print("Number of sublists:", len(superset))
И на выходе
[[], [4], [3], [4, 3], [2], [4, 2], [3, 2], [4, 3, 2], [1], [4, 1] » ], [3, 1], [4, 3, 1], [2, 1], [4, 2, 1], [3, 2, 1], [4, 3, 2, 1]] Количество подсписки: 16
источник
Я не сталкивался с этой
more_itertools.powerset
функцией и рекомендую ее использовать. Я также рекомендую не использовать порядок вывода по умолчаниюitertools.combinations
, часто вместо этого вы хотите минимизировать расстояние между позициями и отсортировать подмножества элементов с меньшим расстоянием между ними выше / перед элементами с большим расстоянием между ними.На
itertools
странице рецептов показано, что он используетchain.from_iterable
r
здесь соответствует стандартным обозначениям для нижней части биномиального коэффициента ,s
обычно упоминается какn
в текстах по математике и на калькуляторах («n Выберите r»)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))
В других примерах здесь приводится набор мощности
[1,2,3,4]
таким образом, что 2-кортежи перечислены в «лексикографическом» порядке (когда мы печатаем числа как целые числа). Если я напишу расстояние между числами рядом с ним (то есть разницу), это покажет мою точку зрения:12 ⇒ 1 13 ⇒ 2 14 ⇒ 3 23 ⇒ 1 24 ⇒ 2 34 ⇒ 1
Правильный порядок подмножеств должен быть порядком, который сначала «исчерпывает» минимальное расстояние, например:
12 ⇒ 1 23 ⇒ 1 34 ⇒ 1 13 ⇒ 2 24 ⇒ 2 14 ⇒ 3
Использование чисел здесь делает этот порядок
["a","b","c","d"]
`` неправильным '', но рассмотрите, например, буквы, это более ясно, почему это может быть полезно для получения набора мощности в таком порядке:ab ⇒ 1 bc ⇒ 1 cd ⇒ 1 ac ⇒ 2 bd ⇒ 2 ad ⇒ 3
Этот эффект более выражен с большим количеством элементов, и для моих целей он определяет разницу между осмысленным описанием диапазонов индексов набора мощности.
(О кодах Грея написано много и т. Д. О порядке вывода алгоритмов в комбинаторике, я не вижу в этом побочной проблемы).
На самом деле я просто написал довольно сложную программу, которая использует этот быстрый код целочисленного раздела для вывода значений в правильном порядке, но затем я обнаружил
more_itertools.powerset
и для большинства применений, вероятно, нормально просто использовать эту функцию следующим образом:from more_itertools import powerset from numpy import ediff1d def ps_sorter(tup): l = len(tup) d = ediff1d(tup).tolist() return l, d ps = powerset([1,2,3,4]) ps = sorted(ps, key=ps_sorter) for x in ps: print(x)
⇣
() (1,) (2,) (3,) (4,) (1, 2) (2, 3) (3, 4) (1, 3) (2, 4) (1, 4) (1, 2, 3) (2, 3, 4) (1, 2, 4) (1, 3, 4) (1, 2, 3, 4)
Я написал несколько более активных участие код , который будет печатать Powerset красиво (см репозитория для печати довольно функций я не включен здесь:
print_partitions
,print_partitions_by_length
, иpprint_tuple
).pset_partitions.py
Это все довольно просто, но все же может быть полезно, если вам нужен какой-то код, который позволит вам сразу получить доступ к различным уровням powerset:
from itertools import permutations as permute from numpy import cumsum # http://jeromekelleher.net/generating-integer-partitions.html # via # /programming/10035752/elegant-python-code-for-integer-partitioning#comment25080713_10036764 def asc_int_partitions(n): a = [0 for i in range(n + 1)] k = 1 y = n - 1 while k != 0: x = a[k - 1] + 1 k -= 1 while 2 * x <= y: a[k] = x y -= x k += 1 l = k + 1 while x <= y: a[k] = x a[l] = y yield tuple(a[:k + 2]) x += 1 y -= 1 a[k] = x + y y = x + y - 1 yield tuple(a[:k + 1]) # https://stackoverflow.com/a/6285330/2668831 def uniquely_permute(iterable, enforce_sort=False, r=None): previous = tuple() if enforce_sort: # potential waste of effort (default: False) iterable = sorted(iterable) for p in permute(iterable, r): if p > previous: previous = p yield p def sum_min(p): return sum(p), min(p) def partitions_by_length(max_n, sorting=True, permuting=False): partition_dict = {0: ()} for n in range(1,max_n+1): partition_dict.setdefault(n, []) partitions = list(asc_int_partitions(n)) for p in partitions: if permuting: perms = uniquely_permute(p) for perm in perms: partition_dict.get(len(p)).append(perm) else: partition_dict.get(len(p)).append(p) if not sorting: return partition_dict for k in partition_dict: partition_dict.update({k: sorted(partition_dict.get(k), key=sum_min)}) return partition_dict def print_partitions_by_length(max_n, sorting=True, permuting=True): partition_dict = partitions_by_length(max_n, sorting=sorting, permuting=permuting) for k in partition_dict: if k == 0: print(tuple(partition_dict.get(k)), end="") for p in partition_dict.get(k): print(pprint_tuple(p), end=" ") print() return def generate_powerset(items, subset_handler=tuple, verbose=False): """ Generate the powerset of an iterable `items`. Handling of the elements of the iterable is by whichever function is passed as `subset_handler`, which must be able to handle the `None` value for the empty set. The function `string_handler` will join the elements of the subset with the empty string (useful when `items` is an iterable of `str` variables). """ ps = {0: [subset_handler()]} n = len(items) p_dict = partitions_by_length(n-1, sorting=True, permuting=True) for p_len, parts in p_dict.items(): ps.setdefault(p_len, []) if p_len == 0: # singletons for offset in range(n): subset = subset_handler([items[offset]]) if verbose: if offset > 0: print(end=" ") if offset == n - 1: print(subset, end="\n") else: print(subset, end=",") ps.get(p_len).append(subset) for pcount, partition in enumerate(parts): distance = sum(partition) indices = (cumsum(partition)).tolist() for offset in range(n - distance): subset = subset_handler([items[offset]] + [items[offset:][i] for i in indices]) if verbose: if offset > 0: print(end=" ") if offset == n - distance - 1: print(subset, end="\n") else: print(subset, end=",") ps.get(p_len).append(subset) if verbose and p_len < n-1: print() return ps
В качестве примера я написал демонстрационную программу CLI, которая принимает строку в качестве аргумента командной строки:
⇣
a, b, c, d, e, f ab, bc, cd, de, ef ac, bd, ce, df ad, be, cf ae, bf af abc, bcd, cde, def abd, bce, cdf acd, bde, cef abe, bcf ade, bef ace, bdf abf aef acf adf abcd, bcde, cdef abce, bcdf abde, bcef acde, bdef abcf abef adef abdf acdf acef abcde, bcdef abcdf abcef abdef acdef abcdef
источник
Если вам нужна определенная длина подмножеств, вы можете сделать это следующим образом:
from itertools import combinations someSet = {0, 1, 2, 3} ([x for i in range(len(someSet)+1) for x in combinations(someSet,i)])
В более общем случае для подмножеств произвольной длины вы можете изменять диапазон диапазонов. На выходе
[(), (0,), (1,), (2,), (3,), (0, 1), (0, 2), (0, 3), (1, 2), (1 , 3), (2, 3), (0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3), (0, 1, 2, 3) )]
источник
def powerset(some_set): res = [(a,b) for a in some_set for b in some_set] return res
источник