0

我有两个清单。第一个看起来像这样:

passOrder = [
                    'direct_diffuse',
                    'direct_specular',
                    'direct_specular_2',
                    'indirect_diffuse',
                    'indirect_specular',
                    'indirect_specular_2',
                    'refraction',
                    'reflection',
                    'emission',
                    'sss'
                ]

另一个是对象列表 - 在本例中为 Nuke 节点:

nodes = nuke.selectedNodes()

我正在尝试将每个节点的名称参数与 passOrder 列表进行比较,并按照 passOrder 中给出的顺序排列它们。我试图显式设置orderedNodes 索引,但我想当列表在开始时为空时这是不可能的。

orderedNodes = []
for n in nodes:
    for index, p in enumerate(passOrder):
        if n['name'].value() == p:
            orderedNodes.insert(index, n)

我也尝试压缩这两个列表,并对它们进行排序 - 这里没有运气。n['name'].value()基本上我不知道在排序时如何迭代组件。

4

3 回答 3

2

我不知道你的类/函数定义是什么样的,所以我使用这些存根来说明我的解决方案:

class Thing:
    def __init__(self, value):
        self.val = value
    def value(self):
        return self.val

class Nuke:
    def __init__(self, name):
        self.n = {"name": Thing(name)}
    def __repr__(self):
        return "Node({})".format(repr(self.n["name".value()))

def selectedNodes():
    return [Nuke("refraction"), Nuke("direct_diffuse"), Nuke("emission")]

您可以 sort nodes,使用passOrder.index它的关键参数:

passOrder = [
                    'direct_diffuse',
                    'direct_specular',
                    'direct_specular_2',
                    'indirect_diffuse',
                    'indirect_specular',
                    'indirect_specular_2',
                    'refraction',
                    'reflection',
                    'emission',
                    'sss'
                ]

nodes = selectedNodes()
nodes.sort(key=lambda item: passOrder.index(item.n["name"].value()))
print nodes

结果:

[Node('direct_diffuse'), Node('refraction'), Node('emission')]
于 2016-10-11T13:03:39.650 回答
1

您不必自己编写排序代码。

ordered_nodes = sorted(nodes, key=lambda n: passOrder.index(n["name"].value()) if n["name"].value() in passOrder else len(passOrder))
于 2016-10-11T13:09:42.520 回答
0

您可以像这样构造一个将节点名称映射到节点的字典

nodes_by_name = {n['name'].value(): n for n in nodes}

使用此字典,按所需顺序检索节点很简单:

ordered_nodes = [nodes_by_name[name] for name in passOrder]

如果可能有passOrder没有对应节点的名称,您可以简单地跳过它们:

ordered_nodes = [nodes_by_name[name] for name in passOrder if name in nodes_by_name]

这种方法比尝试使用排序更简单、更有效。

于 2016-10-11T13:09:23.880 回答