Nuke Python对象列表基于其他列表排序

时间:2016-10-11 12:59:46

标签: python list sorting object nuke

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

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()组件。

3 个答案:

答案 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]

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