1

If I have some arrays with unkown length, how do I get the full combination of them? The more methods, the better! for example:

lista, listb, listc = ['abc', 'asd'], ['zxc', 'rty', 'fgh'], ['uio']

RESULT

result = ['abczxcuio', 'abcrtyuio', ···]

Maybe this problem can be solved recursively, right? But I'm such a novice that I haven't been able to understand the essence of recursion.

Thank you very much :)

Vishal Akkalkote
  • 903
  • 10
  • 16
杨振国
  • 21
  • 4
  • This question might be a bit broad, but you are on the right track with recursion. Think "each element of the first list, combined with each combination of the remaining lists." – tobias_k Apr 21 '21 at 14:04
  • Does this answer your question? [Generating Combinations in python](https://stackoverflow.com/questions/3169825/generating-combinations-in-python) – Manuel Apr 21 '21 at 14:45
  • @Manuel The link is very useful! Thank you for your reply! – 杨振国 Apr 21 '21 at 15:26

2 Answers2

0

You do it with nested loops:

for a in lista :
    for b in listb :
        for c in listc :
            add (a + b + c) to output

If you don't know how many of these arrays are given to you, in a list say, then you will need to use recursion to in effect build this nested loops structure.

In a pattern-matching equational pseudocode,

combine( [lista, ...lists] )  =  for a in lista: go( [a], lists )

go( abc, [listd, ...lists] )  =  for d in listd: go( abc+[d], lists)

go( abcd, [] )  =  ....handle the combination abcd....

Handle the edge cases, to make it work.

This can be implemented with indexing/pointer juggling to make it efficient, in C-like languages, without allocating too much of an extra memory (except for the output of course).

This approach is known as .

Creating an interim structure to produce the result will grow very large very fast -- the number of combinations is in fact exponential. With this approach you get to do the work only once inside the most nested loop.

P.S. More links to explore: 1, 2, 3, 4, 5, 6, 7...

Will Ness
  • 62,652
  • 8
  • 86
  • 167
  • Your pseudocode looks very similar to the idea I started with, but my coding ability is very poor. Could you please spend a few minutes to implement it in a common programming language? Thank you! – 杨振国 Apr 21 '21 at 15:53
  • not sure about "common" but see some [here](https://stackoverflow.com/search?tab=newest&q=user%3a849891%20%5brecursive-backtracking%5d) and specifically [this](https://stackoverflow.com/questions/50086393/representing-an-amount-of-money-with-specific-bills/50087510#50087510) (which has some links in it as well) and [this](https://stackoverflow.com/questions/49848994/how-to-generate-all-the-permutations-of-elements-in-a-list-one-at-a-time-in-lisp/49907365#49907365). and [this](https://codereview.stackexchange.com/questions/224964/print-sums-of-all-subsets/224996#224996). there are more... – Will Ness Apr 21 '21 at 15:56
  • [some here](https://stackoverflow.com/search?q=user%3A849891+nested+loops), e.g. [this](https://stackoverflow.com/questions/59340194/understanding-peter-norvigs-permutation-solution-in-paip/66033083#66033083). also [this](https://stackoverflow.com/questions/65343403/how-does-recursive-backtracking-work-computerphile-sodoku-solver/65361096#65361096). – Will Ness Apr 21 '21 at 16:03
  • Well, thank you very much~ – 杨振国 Apr 22 '21 at 04:02
  • [you're welcome.](https://stackoverflow.com/help/privileges) BTW the answer which you've accepted works by creating interim structure, which will grow very large very fast -- the number of combinations is in fact exponential. with my approach you get to do the work only once inside the most nested loop. – Will Ness Apr 22 '21 at 05:06
0

It's pretty simple to think of a recursive approach:

If there is only one list, return it. Or else, generate all combinations of the last two lists, remove them, add the combinations to the list and repeat for n-1 lists, where n was the initial number of lists. Example:

def generate(lists):
    # lists is a 2D list i.e list of lists
    if len(lists)<2:
        return lists    #base case
    list1, list2 = lists[-2], lists[-1]
    lists.pop()
    lists.pop()
    combinations = []
    for i in list1:
        for j in list2:
            combinations.append(i+j)
    lists.append(combinations)
    return generate(lists)

lists = [['abc', 'asd'], ['zxc', 'rty', 'fgh'], ['uio']]
print(generate(lists))
# prints [['abczxcuio', 'abcrtyuio', 'abcfghuio', 'asdzxcuio', 'asdrtyuio', 'asdfghuio']]
Abhinav Mathur
  • 2,707
  • 2
  • 6
  • 18