0

I would like to make this simplified so that I can control how many nested for loops there are. Essentially this would be 3

for d1 in ['left','right','up','down']:
    for d2 in CreateDirectionList(d1):
        for d3 in CreateDirectionList(d2):
            #Do something with list [d1, d2, d3]
return False

and 4 would be

for d1 in ['left','right','up','down']:
    for d2 in CreateDirectionList(d1):
        for d3 in CreateDirectionList(d2):
            for d4 in CreateDirectionList(d3):
                #Do something with list [d1, d2, d3, d4]
return False

I am pretty much a beginner.

CreateDirectionList just returns a list with 2 strings based on a string input

mazore
  • 984
  • 5
  • 11
  • What exactly are you trying to do? Just create all the different permutations of directions? – Paul M. Mar 25 '20 at 23:47
  • I think I understand what you are asking and I would answer your question if you left it open. – kpie Mar 25 '20 at 23:49
  • I didnt close it – mazore Mar 25 '20 at 23:50
  • oh it was closed because it was simalar to https://stackoverflow.com/questions/48395838/how-to-nest-itertools-products – mazore Mar 25 '20 at 23:51
  • Yeah but it's not a set product... I seriously doubt the attached question satisfies the OPs question. – kpie Mar 26 '20 at 00:11
  • w/e I posted an answer for this question under the other question... – kpie Mar 26 '20 at 00:18
  • Does this answer your question? [Using itertools.product in place of double-nested for loop in Python 3](https://stackoverflow.com/questions/38362368/using-itertools-product-in-place-of-double-nested-for-loop-in-python-3) – Christopher Saia Mar 26 '20 at 05:23

2 Answers2

0

You could pretty easily do this with a recursive generator function:

def gen(values, value_list_factory, depth):
    if depth == 0: # base case
        yield ()
        return

    for x in values:
        for rest in gen(value_list_factory(x), value_list_factory, depth-1):  # recurse!
            yield x, *rest

You've not specified how your CreateDirectionList function works, so here's an example of my generator working with a factory function that removes the passed in value from the starting sequence of ['left','right','up','down'] (this means you never get the same value twice in a row).

directions = ['left','right','up','down']

def create(dir):
    return [x for x in directions if x != dir]

for d1, d2, d3 in gen(directions, create, 3):
    print(d1, d2, d3)

The output is:

left right left
left right up
left right down
left up left
left up right
left up down
left down left
left down right
left down up
right left right
right left up
right left down
right up left
right up right
right up down
right down left
right down right
right down up
up left right
up left up
up left down
up right left
up right up
up right down
up down left
up down right
up down up
down left right
down left up
down left down
down right left
down right up
down right down
down up left
down up right
down up down
Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • Thanks, it works. Although CreateDirectionList basically just makes it alternate horizontal and vertical, but I can figure that out – mazore Mar 26 '20 at 06:30
  • Sure, just pass your `CreateValueList` as the factory argument and the generator should work. I only commented on it because I couldn't give example output that will match what you expect. – Blckknght Mar 26 '20 at 07:12
0

yeah recursion is your friend.

def CreateDirectionList(d):
    if d == "left" or d == "right":
        return ['up','down']
    if d == "up" or d == "down":
        return ['left','right']

def nMoreSteps(d,n):
    if n == 0:
        return [[d]]
    else:
        results = []
        for k in CreateDirectionList(d):
            for k2 in nMoreSteps(k,n-1):
                results.append([d]+k2)
        return results

def nSteps(n):
    results = []
    for d1 in ['left','right','up','down']:
        results += nMoreSteps(d1,n-1)
    return(results)

for k in nSteps(4):
    print(k)
kpie
  • 9,588
  • 5
  • 28
  • 50