Python - 如何按列表列表的最后一个元素对列表列表进行排序?

时间:2015-02-01 04:09:48

标签: python sorting vector

我有一个n值向量列表和n个时间向量列表。我想根据每个值向量的最后一个元素对时间向量进行排序。我想到每个时间向量附加相应值向量的最后一个元素,然后使用

time_vector.sort(key=lambda x: x[-1]) #or
time_vector.sort(key=itemgetter(-1))

最后弹出每个时间向量的最后一个元素。 但是,我认为必须有一种更简单的方式来做到这一点。我还没有能够在Python参考中找到任何关于此问题的示例以进行排序和排序。

使用Alex-Martelli提出的解决方案扩展了问题。因为我必须重新排序值向量v_v和时间向量t_v,Alex提供一站式解决方案

(v_v, t_v) = zip(*sorted (zip(v_v, t_v),key=lambda v: v[0][-1]))

我不明白解压缩是如何工作的,但我只是从Python的文档中复制它,它可以工作。另外一个问题是为什么这不能使用itemgetter()而不是lambda,以及它为什么不使用vector.sort()方法而不是使用函数sorted()

我用来测试上述数字的例子是

v_v = [[1, 2], [2, 3], [3, 1], [5, 3, 4]]
t_v = [[1, 1], [5, 6], [9, 8], [3, 10, 1]]

产生

的排序结果
v_v = ([3, 1], [1, 2], [2, 3], [5, 3, 4])
t_v = ([9, 8], [1, 1], [5, 6], [3, 10, 1])

1 个答案:

答案 0 :(得分:4)

因为这两个载体是 - 并且显然需要保留! - 分开,这是一个好的旧DSU的例子 - 装饰,排序,不装饰。

result = [t for v, t in
          sorted(zip(value_vector, time_vector), key=lambda vt: vt[0][-1])]

key= arg的添加几乎消除了在大多数情况下理解DSU的需要 - 它为你做装饰(只要它只是每个项目的功能)和之后的未装饰那种。

但是在这里,排序键是只是项目的一个功能 - 它是列表中项目的位置的一个功能,用于索引a单独的并行列表(Python中非常不寻常的数据排列)。然而你想要对进行排序(尽管它们本身与所需的顺序完全无关!) - 这就是困难的症结所在。

或者,考虑对位置进行排序,然后使用这些位置对时间进行重新排序。这可能感觉有点不太奇怪:-)。它可以折叠成单个语句,但是当它呈现为两个时可能更清晰:

idx_val = sorted(enumerate(value_vector), key=lambda i, v: v[-1])
result = [times_vector[i] for i, _ in idx_val]

我认为这可能更清楚,因为idx_val(index, value)对的正确排序列表,我们实际上并不关心value,但需要它进行排序) “粘”在时间上然后必须再次被扯掉 - 相反,我们只是使用列表理解中的指数。命名和分成两步有助于。

(但是当然如果你是“一个声明他们所有人的声明”的恶魔,你可以用sorted来代替idx_val名称代替OrderedDict来恢复单身声明 - 根本没有真正的优势,但对于错误的人,“更酷”: - )]

补充说:DSU的另一种形式是import collections od = collections.OrderedDict( sorted(zip(value_vector, time_vector), key=lambda v, t: v[-1])) result = list(od.values()) - 只是一种不同的“未装饰”方式,真的。但是有一位评论者提到它,所以这就是 - 你判断它是否具有任何价值。

dict

我实际上认为通过将未修饰隐藏在{{1}}子类的键/值播放中,它会让事情变得更加模糊。但是,de gustibus ...