Is there any way to nest one for N times?

Asked

Viewed 204 times

-2

In Python is there any way to nest one for inside the other N times? Or is there some kind of algorithm that simulates this?

Basically I need to create a function, which performs combinations of values that are within sublists of size 6, but the number of sublists is something variable, in the example below simulates the idea of a code that uses a number of sublists = 2. If the number of sublists was = 3, there would be 3 be nested and there would be the .append(elementosL1,elementosL2,elementosL3).

combinacoes = [[1,2,3,4,5,6],[12,15,16,13,-4,2]]
def criadorCombinacoes(combinacoes):
    listaCombinacoesPossiveis = []
    for elementosL1 in combinacoes[0]:
        for elementosL2 in combinacoes[1]:
            listaCombinacoesPossiveis.append([elementosL1,elementosL2])
    return listaCombinacoesPossiveis
  • I don’t understand your point. Is there any example of how you would want to use this structure?

  • 4

    It smells like recursiveness to me, but it’s really not clear what you want to know.

  • You need to generate all possible combinations?

  • yes, this is a piece of a Joy Force.

  • If N varies, it is case of recursion or some kind of stacking.

2 answers

5


Yes, and no. It depends on what you want to do.

If each level has its own characteristics, it has practically no way. It would have, but it takes so much work that doing it manually is easier and beautiful.

If everyone does the same thing then you don’t need what you’re saying, just add an extra level of for and it will work like this extra nesting. For example, let’s say you want to scroll through an array where you don’t know how many dimensions it has. The number of dimensions (N according to the question) will be evaluated in a for, then every execution of this loop will be a dimension of the matrix to travel, so you don’t need to nest more than once.

Then it’s likely that doing a recursive function is more interesting. Something like this:

Already has a mechanism ready to do most of what you want with this itertools:

from itertools import product 

for i in product(*[[1,2,3,4,5,6],[12,15,16,13,-4,2]]): 
    print(i)
for i in product(*[[1,2,3,4,5,6],[12,15,16,13,-4,2],[123,154,165,136,-41,22]]): 
    print(i)

I put in the Github for future reference.

If you want to do something yourself just take the source of this function to have a basis.

Apart from that, I could create a code generator, but I doubt it’s necessary, and if I fell for what I initially said, it’s so much work that probably making manual nesting is easier.

Just remember that if this N it is very large it can almost become impossible to perform it, it creates almost infinite executions very fast because it becomes exponential, so nesting manual can be simpler in many cases.

1

Usually, if you have an algorithm that will actually need an arbitrary number of loops inside each other, you use just recursive functions.

You place a single loop in the recursive function - and, if necessary, it calls it again.

In that case, it could be:

def combine_sequences(sequences, combination=(), result=None):
    if result is None:
        result = []

    if not sequences:
        if combination:
            result.append(combination)
        return result

    for element in sequences[0]:
        combine_sequences(sequences[1:], combination + (element,), result)
    return result

So the logic basically is: if the received sequence containing the other subsequences is empty, return the current result. The key is to pass to the function itself the partial result of the "above" executions - in this case the composition combination + (element,) .

In the case of this algorithm, however, it is possible to do interactively as well - just keep the partial results of each sub-sequence, and for each element in the next sequence, also process all previous partial results. You only need 2 bows.

def combine_seq(seq):
    result = []
    for subseq in seq:
        if not result:
            for element in subseq:
                result.append((element,))
        else:
            new_result = []
            for element in subseq:
                for combination in result:
                    new_result.append(combination + (element,))
            result = new_result

    return new_result 

And finally, again, for this specific algorithm, as well as some others, Python has the function ready in the standard library.

The way itertools allows this (under the name of product) and various other combinations of elements - in this case:

In [230]: import itertools

In [232]: list(itertools.product(*[(1,2), (3,4, 5), (5, 6)]))
Out[232]: 
[(1, 3, 5),
 (1, 3, 6),
 (1, 4, 5),
 (1, 4, 6),
 (1, 5, 5),
 (1, 5, 6),
 (2, 3, 5),
 (2, 3, 6),
 (2, 4, 5),
 (2, 4, 6),
 (2, 5, 5),
 (2, 5, 6)]

Browser other questions tagged

You are not signed in. Login or sign up in order to post.