I have a tuple.a = ('a1','a2','a3')
.
I want to find all the subsets of it except the null set. My question is: 'is there any built-in function for doing it?'. It should return ('a1'),('a2'),('a3'),('a1','a2'),('a2','a3'),('a3','a1').
Asked
Active
Viewed 491 times
0

mihir shanvir
- 193
- 1
- 1
- 13
-
1what you are trying to do is find whats known as the power set (without the empty set) use that in google, and you will find the answer – Crimson Jun 11 '17 at 17:43
2 Answers
4
You can use itertools.combinations
and itertools.chain
In [13]: from itertools import combinations, chain
In [14]: a = ('a1','a2','a3')
In [15]: list(chain(*(combinations(a, i) for i in xrange(1, len(a)))))
Out[15]: [('a1',), ('a2',), ('a3',), ('a1', 'a2'), ('a1', 'a3'), ('a2', 'a3')]

Akavall
- 82,592
- 51
- 207
- 251
-
Great work combining `combinations` and `chain`. Demonstrates the power of itertools module. – xssChauhan Jun 11 '17 at 17:46
-
-
Why not `chain.from_iterable`, so you can avoid unpacking the generator expression. – Moses Koledoye Jun 11 '17 at 17:47
-
@MihirShanvir The * in this case is being used to unpack the iterable. [More information here](https://stackoverflow.com/questions/400739/what-does-asterisk-mean-in-python) – Will Da Silva Jun 11 '17 at 17:50
-
@MosesKoledoye, because I con't quite remember that syntax, I think `chain.from_iterable` is preferred, but since @dawg already uses it in his answer, I am going to leave mine the way it is. – Akavall Jun 11 '17 at 17:52
4
There is a recipe for power sets in itertools:
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))
With your example:
>>> list(it.chain.from_iterable(it.combinations(a, r) for r in range(1, len(a)+1)))
[('a1',), ('a2',), ('a3',), ('a1', 'a2'), ('a1', 'a3'), ('a2', 'a3'), ('a1', 'a2', 'a3')]

dawg
- 98,345
- 23
- 131
- 206