-2

I'm trying to find an elegant way to generate all possible combinations from an initial flat list.

For example:

[In:]

l = ["aaa", "bbb", "ccc"]

[Out:]

[["aaa"], ["bbb"], ["ccc"]]
[["aaa", "bbb"], ["ccc"]]
[["aaa", "ccc"], ["bbb"]]
[["bbb", "ccc"], ["aaa"]]
[["aaa", "bbb", "ccc"]]

As you see here the order doesn't matter for me. So I would avoid to obtain such cases:

[["aaa"], ["bbb"], ["ccc"]]
[["bbb"], ["aaa"], ["ccc"]]
...
[["ccc"], ["aaa"], ["bbb"]]

Also each sublist of my output list has to contain every element of my initial list.

I din't find any obvious solution with itertools.combination()

Thanks

Robin De Schepper
  • 4,942
  • 4
  • 35
  • 56
  • Does this answer your question? [How to get all subsets of a set? (powerset)](https://stackoverflow.com/questions/1482308/how-to-get-all-subsets-of-a-set-powerset) – Serial Lazer Nov 09 '20 at 11:25
  • Thanks for your answer. Not really, I forgot to specify that the format of my output should be List[List[Any]] and where every element of my initial list has to be within each sublists. Am I clear? – Thomas Karaouzene Nov 09 '20 at 11:30
  • How does it matter if you any `ints` or `List[Any]` as elements in the list? What you eventually need is to generate the powerset. I think the above answer shld suffice with minor modifications – Serial Lazer Nov 09 '20 at 11:33
  • It is may be me the problem but I don't see how it solve my issue. What I would is a list of lists where all sub lists contain every single element of the input list. – Thomas Karaouzene Nov 09 '20 at 11:51
  • In their example, `powerset(["aaa", "bbb"])` produce `[(), ('aaa',), ('bbb',), ('aaa', 'bbb')]` where I would `[["aaa", "bbb"], [["aaa"], ["bbb"]]]` – Thomas Karaouzene Nov 09 '20 at 11:58
  • What's the problem with simply just ignoring the empty set and take the remaining answer? – Serial Lazer Nov 09 '20 at 12:06
  • The problem is not the empty set. The proble is that I would expect `[[('aaa',), ('bbb',)]...]` instead of `[('aaa',), ('bbb',)...]`. – Thomas Karaouzene Nov 09 '20 at 12:23
  • Just convert each element in the powerset from a tuple to a list, using `list()`. What am I missing? – Serial Lazer Nov 09 '20 at 12:24
  • the two first elements `('aaa',)` and `('bbb',)` has to be in the same sublist – Thomas Karaouzene Nov 09 '20 at 12:26
  • Yes I did, in case where the input contains more than 3 elements it is much more complex – Thomas Karaouzene Nov 09 '20 at 12:43

1 Answers1

2

Question is quite vague, I think what you are looking for is set-partitions:

def partition(collection):
    if len(collection) == 1:
        yield [ collection ]
        return

    first = collection[0]
    for smaller in partition(collection[1:]):
        # insert `first` in each of the subpartition's subsets
        for n, subset in enumerate(smaller):
            yield smaller[:n] + [[ first ] + subset]  + smaller[n+1:]
        # put `first` in its own subset 
        yield [ [ first ] ] + smaller


something = ['a', 'b', 'c']

for n, p in enumerate(partition(something), 1):
    print(n, sorted(p))

Output:

1 [['a', 'b', 'c']]
2 [['a'], ['b', 'c']]
3 [['a', 'b'], ['c']]
4 [['a', 'c'], ['b']]
5 [['a'], ['b'], ['c']]
Serial Lazer
  • 1,667
  • 1
  • 7
  • 15
  • As output I would `[[['a'], ['b'], ['c']], [['a', 'b'], ['c']], [['a', 'c'], ['b']], [['b', 'c'], ['a']], [['a', 'b', 'c']]]` – Thomas Karaouzene Nov 09 '20 at 12:52
  • Your question is quite vague. I think what you are looking for is set-partitions. Modified my answer to return partitions instead – Serial Lazer Nov 09 '20 at 13:04