繁体   English   中英

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

[英]Python - How to sort a list of lists by last element of another list of lists?

我有一个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])

由于两个向量是-显然需要保留! -分开,这是旧DSU的一种情况-装饰,排序,未装饰。

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

在大多数情况下, key= arg的添加几乎消除了对DSU的了解-它为您进行装饰(只要它只是每个项目的功能),并且也可以进行排序后的修饰。

但是在这里,排序键不仅是项的函数,而且还是项在列表中位置的函数,您可以用它来索引单独的并行列表(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但需要该value进行排序)不会“胶合”到当时的水平再次撕掉-而是我们只使用列表推导中的索引。 命名和分为两个步骤会有所帮助。

(但是,当然,如果您是“一个统治一切的语句”的恶魔,则可以将已sorted调用替换为listcomp来代替idx_val名称,然后返回到单个语句-根本没有真正的优势,但是,对错误的人,“冷却器” :-)]

补充:DSU的另一种伪装是OrderedDict实际上,这是“取消装饰”的另一种方式。 但是有一个评论者提到它,所以在这里-您可以判断它是否具有任何价值。

import collections
od = collections.OrderedDict(
    sorted(zip(value_vector, time_vector),
           key=lambda v, t: v[-1]))
result = list(od.values())

我实际上认为,通过隐藏dict子类的键/值操作中的修饰,可以使事情变得更加模糊。 但是,de gustibus ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM