python 2.7 - 使用新的“order”约束重新排序列表的输出

时间:2013-08-03 18:46:41

标签: python list csv tetgen

我知道c ++中的一些基础知识,但我是python的初学者。

我有一段工作代码(见下文),我想添加一个约束来格式化它的输出,我无法弄清楚如何做...

让我先解释一下该计划的作用:

我有一个输入文件colors.csv,其中包含一个颜色列表,一种颜色是一行:颜色是由它们的名称和比色坐标X,Y和Z定义的,它看起来是这样的:

Colorname, X1, Y1, Z1
Colorname2, X2, Y2, Z2
...etc.

给定另一个输入文件targets.csv中包含的任何XYZ坐标列表,程序将在输出文件output.txt

中为我提供解决方案列表

这个解决方案是通过使用tetgen对点云进行第一次三角测量,然后是四面体中点的重心坐标来计算的(但这里解释所有内容并不重要......)

解决方案的格式为:

target, name0, density0, name1, density1, name2, density2, name3, density3

总是只有4个名字和相关的密度。

它会看起来像这样的例子:

122 ,PINKwA,0.202566115168,GB,0.718785775317,PINK,0.0647284446787,TUwA,0.0139196648363

123 ,PINKwA,0.200786239192,GB,0.723766147717,PINK,0.0673550497794,TUwA,0.00809256331169

124 ,PINKwA,0.19900636349,GB,0.72874651935,PINK,0.0699816544755,TUwA,0.00226546268446

125 ,OR0A,0.00155317194109,PINK,0.0716160265958,PINKwA,0.195962072115,GB,0.730868729348

126 ,OR0A,0.00409427478508,PINK,0.0726192660009,PINKwA,0.192113520109,GB,0.731172939105

127 ,OR0A,0.00663537762906,PINK,0.073622505406,PINKwA,0.188264968103,GB,0.731477148862

我现在想做什么?

出于实际原因,我希望我的输出遵循一定的顺序。 我想要一个优先列表"统治name, density输出的顺序。

我的实际程序按照我不理解的顺序输出颜色名称,但无论如何我需要这些颜色名称按特定顺序排列,例如PINK应始终是第一个{{} 1}}第二个,等等。

而不是:

PINKwA

我想要;

127 ,OR0A,0.00663537762906,PINK,0.073622505406,PINKwA,0.188264968103,GB,0.731477148862

因为我的优先列表是:

127 ,PINK,0.073622505406,PINKwA,0.188264968103,OR0A,0.00663537762906,GB,0.731477148862

我怎么能简单地将此功能添加到下面的代码中?有什么想法吗?

已编辑的代码(有效......):

0, PINK
1, PINKwA
2, OR0A
3, GB

1 个答案:

答案 0 :(得分:1)

首先,您需要直接在Python代码中编码优先级列表:

priority_list = {
    'PINK': 0,
    'PINKwA': 1,
    'OR0A': 2,
    'GB': 3,
}

这将让您快速检索给定颜色名称的顺序。然后,您可以使用key参数sorted按名称对其名称进行排序。但重要的是,您需要检索排序的名称,而不是排序名称的索引,就像http://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html一样。

sorted_indices = sorted(enumerate(names), key=lambda (i, name): priority_list[name])

enumerate builtin在原始名称列表中使用其索引标注每个名称,然后sorted内置根据其在优先级列表中的排名对所得(i, name)对进行排序。然后我们可以将名称写入文件,然后是bcoords数组中相应的元素(使用索引值)。

for i, name in sorted_indices:
    output.write(',%s,%s' % (name, bcoords[i]))

所以,这就是我在你的代码中使最终块看起来像:

names = [colors[i][0] for i in tg.tets[tet_i]]
output.write(target[0])
for i, name in sorted(enumerate(names), key=lambda (i, name): priority_list[name]):
    output.write(',%s,%s' % (name, bcoords[i]))
output.write('\r\n')
output.close()

在这里,我将文件输出策略更改为Pythonic - 通常,将字符串添加到一起基本上没有完成,最好是创建格式字符串并填充变量(您也可以使用{{1}在字符串上执行此操作)。此外,您可以对.format()进行多次调用,他们只会继续向文件写入字节,因此无需一次创建一个大的长字符串来写出来。最后,无需在.write()上调用str,因为它已经是字符串。