1

I need to run through db using recursion and get a list of results at the end. Function works correct (if print unrem) but I cann't return the list of results.

def find_locks(item, ids):
    if item.video_id:
        #print (item.video_id, ids)
        return (item.video_id, ids)
    for i in CatalogItem.objects.filter(parent=item):
        if i.is_lock:
            find_locks(i, ids.append(i.id))
        else:
            find_locks(i, ids)

How can I get the list results?

3
  • Can you write some input and output examples? Commented Nov 21, 2013 at 10:43
  • you only return results in the 'if' branch. Commented Nov 21, 2013 at 10:44
  • you need an assignment for find_locks or return find_locks Commented Nov 21, 2013 at 10:45

3 Answers 3

3

I'd use a recursive generator instead of building a list:

def find_locks(item, ids):
    if item.video_id:
        yield (item.video_id, ids)
    for i in CatalogItem.objects.filter(parent=item):
        nxt = ids + [i.id] if i.is_lock else ids
        for x in find_locks(i, nxt):
            yield x

In python 3.3 you can use yield from for the last part.

Sign up to request clarification or add additional context in comments.

1 Comment

I think this variant is the best, but ids always return as empty list, the real data has lists with ids.
1

Try something like the following:

def find_locks(item, ids):
    if item.video_id:        
        return [(item.video_id, ids)]
    res = []
    for i in CatalogItem.objects.filter(parent=item):
        if i.is_lock:
            res.extend(find_locks(i, ids + [i.id]))
        else:
            res.extend(find_locks(i, ids))
    return res

In the base case you return list with the only one item included. If it's not the base case, you make a new list, execute recursive call, extend the list with result of recursive call and return this list.

1 Comment

I know it was in the OP by greg as well, but ids.append(i.id) will return None, which is probably not what he had in mind.
1

You can simply store each result in a list and return that at the end:

def find_locks(item, ids):
    if item.video_id:
        return [(item.video_id, ids)]
    result = []
    for i in CatalogItem.objects.filter(parent=item):
        if i.is_lock:
            result.extend(find_locks(i, ids + [i.id]))
        else:
            result.extend(find_locks(i, ids))
    return result

Note that you need to return each item in a list as well because other calls to find_locks expect to receive a list as return value.

1 Comment

I know it was in the OP by greg as well, but ids.append(i.id) will return None, which is probably not what he had in mind.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.