15

I'm trying to create a powerset in Python 3. I found a reference to the itertools module, and I've used the powerset code provided on that page. The problem: the code returns a reference to an itertools.chain object, whereas I want access to the elements in the powerset. My question: how to accomplish this?

Many thanks in advance for your insights.

3
  • 2
    related: what's a good way to combinate through a set? Commented Oct 30, 2016 at 22:52
  • @BruceM, is it necessarily to use itertools? Commented Apr 3, 2019 at 5:10
  • there is a powerset function in the more_itertools library more_itertools.powerset(iterable) Commented Sep 15, 2024 at 8:40

3 Answers 3

41

itertools functions return iterators, objects that produce results lazily, on demand.

You could either loop over the object with a for loop, or turn the result into a list by calling list() on it:

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))

for result in powerset([1, 2, 3]):
    print(result)

results = list(powerset([1, 2, 3]))
print(results)

You can also store the object in a variable and use the next() function to get results from the iterator one by one.

Sign up to request clarification or add additional context in comments.

Comments

4

Here's a solution using a generator:

from itertools import combinations

def all_combos(s):
    n = len(s)
    for r in range(1, n+1):
        for combo in combinations(s, r):
            yield combo

1 Comment

Thank you. I have stolen your answer with some modifications. Power sets, at least as defined math, include the empty set, so your range should start at 0. And power sets should treat any duplicated input element as just occurring once. See github.com/jpgoldberg/powerset-generator for a package I'm developing based on your answer.
2

Allen Downey's answer is what I would use, except I would replace the range with range(n+1) since the empty set is considered an element of the power set.

This code can easily be rewritten as a one liner:

(combo for r in range(len(s) + 1) for combo in combinations(s, r))

Your choice whether to surround it with () for an iterator or [] for a list.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.