2

I have a set Elements that have multiple other elements nested inside of them. I am trying to extract all of them through recursion since I don't know how many levels deep does the nesting go. To compare this to something more pythonic i would say imagine a list of elements. Each item on that list can either be a single value or another list of elements. Then for each sub-list there can be either a single value or more sub-lists. I want to go through all of them and pull out each element from all of the list until the last of sub-lists have nothing but single items on it.

lst = [1,[[2,3,4],[5,6,7]],[[8,9,10],[[11,12,13],[14,15,16]]],17,18]
for i in lst:
    subElem = i.GetSubComponentIds()
        if subElem.Count >= 1:
            idsList.append(subElem)
            for i in subElem:
                subElem2 = i.GetSubComponentIds():
                    if subElem2.Count = >= 1:.... and so on

How would I set up a recursive function that would grab every element on a input list run a GetSubComponentIds() function on it (that either returns another list or nothing). if the return is a list then run the same function GetSubComponentsIds() on each item of that sublist until you get nothing in return. At the same time for those that returned nothing i want that Id appended. So if i used the lst from the example above i would end up with a list of all of the elements 1-18 (the only trick is that i donk know how many sub lists deep each element on the original list is).

konrad
  • 3,544
  • 4
  • 36
  • 75
  • no its not because when the original list comes in its "packed" and i dont know if there are more sublists nested inside of each element. I am trying to explain this with a list of lists example but its not a list of lists rather something like it but only after you unpack it. – konrad Aug 05 '14 at 04:35
  • 1
    The approaches shown in that question are still applicable. If you are working with something that isn't a list, then you need to specify what it is (give us at least a basic definition). We can't work with types we can't see. In the description you have provided, you don't show the *termination case* -- how would we obtain the ID if there is no sub-list? – cdhowie Aug 05 '14 at 04:36
  • If you *only* want the length of the resulting flat list, then your question might call for a slightly tweaked version of the answer in the suggested duplicate- since you seem to want a flat list of the items as well, the duplicate seems to match your question exactly. – Marius Aug 05 '14 at 04:39
  • It's a "family instance" as defined in Revit API. You can nest more families inside of family. That's why i don't know if there are any unless i run GetSubComponentIds() on it. If it returns a list then its a list of more families nested inside. Then I want to run the same method on each one of the nested families to see if they have any more nested families inside of them. – konrad Aug 05 '14 at 04:39
  • 1
    For the example input `[1,[[2,3,4],[5,6,7]],[[8,9,10],[[11,12,13],[14,15,16]]],17,18]` shown in your code, **exactly** what output do you want? – Karl Knechtel Aug 05 '14 at 04:58

2 Answers2

1

As I understand it, you want to use recursion to extract the elements buried in some nested object. Here is one method:

def is_list(x):
    # Replace this with an appropriate test for your type
    return hasattr(x, 'index')

def recurse(lst):
    if is_list(lst):
        elements = []
        for element in lst:
            elements += recurse(element)
        return elements
    else:
        return [lst]

Run on your sample list:

>>> recurse(lst)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
John1024
  • 109,961
  • 14
  • 137
  • 171
0

Please refer to following code working with regular lists:

def flattern(lst, res):
    for elem in lst:
        if isinstance(elem, list):
            flattern(elem, res)
        else:
            res.append(elem)

Please update it to using your functions

vadimvolk
  • 711
  • 4
  • 15