Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nuke Python对象列表基于其他列表的顺序_Python_List_Sorting_Object_Nuke - Fatal编程技术网

Nuke Python对象列表基于其他列表的顺序

Nuke Python对象列表基于其他列表的顺序,python,list,sorting,object,nuke,Python,List,Sorting,Object,Nuke,我有两张单子。第一个看起来像这样: passOrder = [ 'direct_diffuse', 'direct_specular', 'direct_specular_2', 'indirect_diffuse', 'indirect_specular',

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

passOrder = [
                    'direct_diffuse',
                    'direct_specular',
                    'direct_specular_2',
                    'indirect_diffuse',
                    'indirect_specular',
                    'indirect_specular_2',
                    'refraction',
                    'reflection',
                    'emission',
                    'sss'
                ]
另一个是对象列表-在本例中为Nuke节点:

nodes = nuke.selectedNodes()
我试图将每个节点的name参数与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()
组件。

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

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")]
您可以使用其关键参数
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')]

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

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")]
您可以使用其关键参数
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')]

您可以构造一个字典,将节点名称映射到如下节点

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]

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

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

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]

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

您不必自己编写排序代码

ordered_nodes = sorted(nodes, key=lambda n: passOrder.index(n["name"].value()) if n["name"].value() in passOrder else len(passOrder))

您不必自己编写排序代码

ordered_nodes = sorted(nodes, key=lambda n: passOrder.index(n["name"].value()) if n["name"].value() in passOrder else len(passOrder))

如果
节点
可能包含名称不在
密码中的核弹,那么这比我的解决方案更可取。好极了。@Kevin谢谢!事实上,我在发布我的解决方案后看到了你的解决方案。@S.de Melo感谢你提供了如此优雅的解决方案。我正在尝试将正则表达式注入此函数,以匹配以passOrder中给定的字符串开头的层名称,例如
direct\u diffuse\u layerName\u 2
。如果
节点
可能包含名称不在
passOrder
中的核,则这比我的解决方案更可取。好极了。@Kevin谢谢!事实上,我在发布我的解决方案后看到了你的解决方案。@S.de Melo感谢你提供了如此优雅的解决方案。我正在尝试将正则表达式注入此函数,以匹配以passOrder中给定的字符串开头的层名称,例如
direct\u diffuse\u layerName\u 2