在 python 中设置迭代项目查询

setting up iterative item query in python

我正在尝试设置一个函数,该函数将查询项目的子组件(如果存在)和 return 其他 return 项目本身。

想象一个可以包含更多对象的对象。要访问这些对象,如果该对象包含子对象,我现在会做 object.GetSubComponentIds(),如果有 none,它将 return 那些子对象的列表或 EmptyList。如果其中包含子对象,我想继续,然后对于每个子对象,我想检查它们中是否包含任何子对象。因此,对于每个 SubObject.GetSubComponentIds() 现在,如果它们不包含任何内容,那么我很乐意 return 它们,同时保持它们来自的对象的嵌套结构。

对象1(包含3个子对象) object2(包含3个子对象,每个子对象又包含一个子对象) object3(不包含子对象)

inputlist = [object1, object2]

outputlist = [[obj1sub1, obj1sub2, obj1sub3],[[obj2sub1sub1],[obj2sub2sub1],[obj2sub3sub1]],[obj3]]

我对维护嵌套列表结构很感兴趣,它可以让我始终追溯子对象的来源。同样,获取子对象列表的方法是 object.GetSubComponentIds(),它将 return 或 listEmpty List

谁能帮我设置一个迭代函数来检索它们。请记住,我不知道一个对象中是否包含任何子对象,或者它们有多深。基本上,如果它 return 是一个列表,我需要检查该列表中的每个项目以获取更多子对象。

提前致谢

这是我的第一次尝试:

#unwrap all elements to use with API
elements = []
for i in IN[0]:
    elements.append(UnwrapElement(i))

#create element set from python list
elementSet = Autodesk.Revit.DB.ElementSet()
for i in elements:
    elementSet.Insert(i)

#convert element set to List[Element]
setForCheck = List[Autodesk.Revit.DB.Element]()
elemIter = elementSet.ForwardIterator()
elemIter.Reset()
while elemIter.MoveNext():
    curElem = elemIter.Current
    setForCheck.Add(curElem)

#iterate throuh all elements to extract nested elements
setLoop = List[Autodesk.Revit.DB.Element]()
elemSet = List[Autodesk.Revit.DB.Element]()
itemOut = []
counter = 0
while setForCheck.Count >= 1:
    setLoop.Clear()
    for i in setForCheck:
        itemOut.append(i)
        if i.GetSubComponentIds().Count >= 1:
            elem = Autodesk.Revit.DB.ElementSet()
            for j in i.GetSubComponentIds():
                elem.Insert(doc.GetElement(j))
            elemIterA = elem.ForwardIterator()
            elemIterA.Reset()
            while elemIterA.MoveNext():
                curElemA = elemIterA.Current
                setLoop.Add(curElemA)
    setForCheck.Clear()
    elemIterB = setLoop.GetEnumerator()
    elemIterB.Reset()
    while elemIterB.MoveNext():
        curElemB = elemIterB.Current
        setForCheck.Add(curElemB)
    counter += 1
    if counter > 1000:
         break

#Assign your output to the OUT variable
OUT = itemOut

您正在使用一些我不熟悉的特定库,例如 Autodesk。让我用一个抽象的例子来回答你的问题。

假设我们正在处理 Thing 个对象,其中 Thing 定义为:

class Thing(object):
    def __init__(self, name):
        self.name = name
        self.inside = []

我们可以制作 Thing 并将其他东西放入其中。你在你的post中给出的例子可以这样写:

ob1 = Thing("ob1")
ob1.inside.extend([Thing("ob1sub1"), Thing("ob1sub2"), Thing("ob1sub3")])

ob2 = Thing("ob2")
for i in xrange(1,4):
    name = "ob2sub{}".format(i)
    thing = Thing(name)
    thing.inside.append(Thing(name + "sub1"))
    ob2.inside.append(thing)

ob3 = Thing("ob3")

things = [ob1, ob2, ob3]

这就是一棵树。现在我们想要 return 树中所有叶节点的嵌套列表:

def search_things(things):
    names = []
    for thing in things:
        if not thing.inside:
            names.append(thing)
        else:
            names.append(search_things(thing.inside))

    return names

一个测试:

>>> search_things(things)
[['ob1sub1', 'ob1sub2', 'ob1sub3'],
 [['ob2sub1sub1'], ['ob2sub2sub1'], ['ob2sub3sub1']],
 'ob3']

我会让你把它转化为你的具体问题,但这是一般的想法。请注意,该算法是递归的,而不是迭代的。你说你想要一个迭代算法——上面可以迭代地写——但这给了你想法。