我有两个清单。第一个看起来像这样:
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()
组件。
答案 0 :(得分:2)
我不知道您的类/函数定义是什么样的,所以我使用这些存根来说明我的解决方案:
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import javax.swing.*;
import javax.swing.UnsupportedLookAndFeelException;
import java.util.Random;
public class Interface {
public static void main(String[] args) {
new Interface();
}
public Interface() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Timer timer;
private long startTime = -1;
private long duration;
private JLabel label;
private JButton start;
public TestPane() {
start = new JButton("Start");
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
timer = new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime < 0) {
startTime = System.currentTimeMillis();
}
long now = System.currentTimeMillis();
long clockTime = now - startTime;
if (clockTime >= duration) {
clockTime = duration;
timer.stop();
}
SimpleDateFormat df = new SimpleDateFormat("mm:ss:SSS");
label.setText(df.format(duration - clockTime));
}
});
timer.setInitialDelay(0);
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!timer.isRunning()) {
duration = new Random().nextInt((10000 - 1000) + 1) + 1000;
startTime = -1;
timer.start();
}
}
});
label = new JLabel("...");
add(label);
add(start);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 250);
}
}
}
您可以使用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")]
为其关键参数排序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
答案 1 :(得分:1)
您不必自己编码。
ordered_nodes = sorted(nodes, key=lambda n: passOrder.index(n["name"].value()) if n["name"].value() in passOrder else len(passOrder))
答案 2 :(得分: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]
这种方法比尝试使用排序更简单,更有效。