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
。