Python - 如何按另一个列表列表的最后一个元素对列表列表进行排序? [英] Python - How to sort a list of lists by last element of another list of lists?

查看:64
本文介绍了Python - 如何按另一个列表列表的最后一个元素对列表列表进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a list of n value vectors and a list of n time vectors. I would like to sort the time vectors based on the last element of each value vector. I thought of appending to each time vector the last element of the corresponding value vector, then using

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

最后弹出每个时间向量的最后一个元素.但是,我认为必须有一种更简单的方法来做到这一点.我一直无法在 Python 的 sort 和 sorted 参考中找到有关此问题的任何示例.

and finally popping out the last element of each time vector. However, I'm thinking there must be a simpler manner to do this. I haven't been able to find any example for this problem in the Python reference for sort and sorted.

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

Expanded Question using Alex-Martelli's proposed solution. Because I have to reorder both value vectors v_v and time vectors t_v, Alex offers a one-stop solution

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

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

I do not understand how unzipping works, but I just copied it from Python's documentation, and it works. The additional question is why this doesn't work using itemgetter() instead of lambda, and why it doesn't work with the vector.sort() method instead of using the function sorted()

我用来测试上面的数值例子是

The numerical examples I used to test the above are

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 的例子 -- 装饰、排序、取消装饰.

Since the two vectors are -- and apparently need to remain! -- separate, this is a case for good old DSU -- decorate, sort, undecorate.

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

添加 key= arg 几乎消除了在大多数情况下理解 DSU 的需要——它为你做装饰(只要它只是每个项目的函数)以及排序后的未修饰.

The addition of the key= arg has almost done away with the need to understand DSU in most cases -- it does the decoration for you (as long as it's just a function of each item) and the undecoration after the sort too.

但在这里,排序键只是项目的函数——它是项目在列表中的位置的函数,你用它来索引一个单独的并行列表(Python 中一种非常不寻常的数据排列).然而,您想要对时间进行排序(即使它们本身与所需的顺序完全无关!)——这是困难的关键.

But here, the sort key is not just a function of the item -- it's a function of the item's position in the list, which you use to index a separate parallel list (a very unusual arrangement of data in Python). Yet you want to sort the times (even though per se they have absolutely nothing to do with the desired order!) -- that's the crux of the difficulty.

或者,考虑对位置进行排序,然后使用这些位置重新排序时间.那可能感觉不那么奇怪了:-).它可以被折叠成一个单独的语句,但如果呈现为两个语句可能会更清晰:

Alternatively, consider sorting the positions, then using those to reorder the times. That may feel a bit less weird:-). It can be collapsed into a single statement, but it may be clearer when presented as two:

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 进一步但需要它进行排序)没有粘在"到时间然后必须再次被扯掉 - 而我们只是使用列表理解中的索引.命名和拆分为两个步骤很有帮助.

I think this may be clearer because the idx_val (properly sorted list of (index, value) pairs where we don't actually care about the value further but need it for the sorting) isn't "glued on" to the times then has to be ripped off again -- rather we just use the indices in the list comprehension. And the naming and the splitting into two steps helps.

(当然,如果你是一个一个语句来统治所有"的恶魔,你可以将 sorted 调用替换为 listcomp 中的 idx_val 名称并回到一个单一的声明 - 根本没有真正的优势,但是,对于错误的人来说,更酷":-)]

(But of course if you're a "one statement to rule them all" fiend you can substitute the sorted call into the listcomp in lieu of the idx_val name and get back to a single statement -- no real advantage at all, but, to the wrong sort of people, "cooler":-)]

补充:DSU 的另一种伪装是 OrderedDict —— 只是一种取消装饰"的不同方式,真的.但是有一位评论者提到了它,所以这里是 - 您可以判断它是否提供任何价值.

Added: another guise of DSU would be an OrderedDict -- just a different way to "undecorate", really. But there's a commenter mentioning it, so here it is -- you be the judge of whether it offers any value.

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

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

I actually think that by hiding the undecorating in the keys/values play of a dict subclass, it makes things murkier. But, de gustibus...

这篇关于Python - 如何按另一个列表列表的最后一个元素对列表列表进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆