break out of a for loop and re-do it with updated list

69 views Asked by At

This is my code:

for parseparent in allgroups:
  for groupPerm in self.permissions["groups"][parseparent]["permissions"]:
    if self.permissions["groups"][parseparent]["permissions"][groupPerm] and (groupPerm not in allgroups):
      allgroups.append(group)
      print("found a child- shall we do again?")

Firstly self.permissions["groups"][parseparent]["permissions"] will be a boolean value, thus my if statement is really reading like "If True and (groupPerm not in allgroups):". Normally the permission will not exist unless it is true, but sometimes they are set to False.

My problem is that if we reach the print statement, I need to re-run this loop because all groups will now have a new member of the list. There is no pre-defined limit of how far nested these could be, so I can't just do a set number of iterations like a range.

My solution is that when I get to print("found a child- shall we do again?"), i need to jump back to and re-do for parseparent in allgroups:. I thought about list comprehension, but I don't know how to do that in this case. most of the examples seem to be for a known, set amount of iterations.

basically, I suppose I am building lists from several dictionaries. here is an example, but only two levels deep (could be more):

allgroups starts out as []
master list = [dict1]
dict1 = {"dict2": True, "item1": True, "item2": False}
dict2 = {"dict3": True, "item4": True, "item5": False}
dict3 = {"Other": True, "item6": True, "item7": False}
dict4 = {"item9": False, "item8": True, "itemz": True}

once done, allgroups should contain [dict1, dict2, item1, dict3, item4, Other, item6] - ideally, I really want it to just contain the dictx items ([dict1, dict2, dict3]), but... this will server my purposes for now.

In a nutshell... start with the parent list, see if one of the items is another list (the child), then see if that child, in turn, has children; until no more subchildren are found.

2

There are 2 answers

1
Eric Levieil On BEST ANSWER

Use a while loop like that:

itemsToProcess = allgroups[:]
while len(itemsToProcess) > 0:        
    parseparent = itemsToProcess.pop(0)
    for groupPerm in self.permissions["groups"][parseparent]["permissions"]:
        if self.permissions["groups"][parseparent]["permissions"][groupPerm] and (groupPerm not in allgroups):
            allgroups.append(groupPerm)
            itemsToProcess.append(groupPerm)
            print("found a child- shall we do again?")
1
Nir Friedman On

It seems like your problem is best addressed with a recursive generator. I'm sorry I don't one hundred per cent understand your structure, but consider the following:

def recurse_yield(d):
    yield d
    for k, v in d.iteritems():
        if v:
            recurse_yield(k)

d1 = {"hey": False}
d2 = {d1: True}

for k in recurse_yield(d2):
    print k

I've done my best to structure it similar to your problem, though e.g.the use of strings that matched actual variables confused me. But the main point is the use of a recursive generator to elegantly traverse the nested structure, hope that helps.