Python 如何根据另一个列表对元组列表进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12814667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to sort a list of tuples according to another list
提问by alwbtc
There is a list:
有一个列表:
a = [("ax", 1), ("ec", 3), ("bk", 5)]
another list:
另一个清单:
b = ["ec", "ax", "bk"]
I want to sort aaccording to b:
我要排序a根据b:
sort_it(a, b)
a = [("ec", 3), ("ax", 1), ("bk", 5)]
How to do this?
这该怎么做?
采纳答案by Amber
a.sort(key=lambda x: b.index(x[0]))
This sorts ain-place using the the index in bof the first element of each tuple from aas the values it sorts on.
这a使用b每个元组的第一个元素的索引a作为它排序的值进行就地排序。
Another, possibly cleaner, way of writing it would be:
另一种可能更简洁的写法是:
a.sort(key=lambda (x,y): b.index(x))
If you had large numbers of items, it might be more efficient to do things a bit differently, because .index()can be an expensive operation on a long list, and you don't actually need to do a full sorting since you already know the order:
如果你有大量的项目,用不同的方式做事情可能会更有效,因为.index()在一个长列表上可能是一个昂贵的操作,你实际上不需要做一个完整的排序,因为你已经知道顺序:
mapping = dict(a)
a[:] = [(x,mapping[x]) for x in b]
Note that this will only work for a list of 2-tuples. If you want it to work for arbitrary-length tuples, you'd need to modify it slightly:
请注意,这仅适用于 2 元组列表。如果您希望它适用于任意长度的元组,则需要稍微修改它:
mapping = dict((x[0], x[1:]) for x in a)
a[:] = [(x,) + mapping[x] for x in b]
回答by fritz-johann
Another posibility is to sort a, sort the indices of baccording to band than sort the aaccording to the indices
另一个posibility是排序a,排序的索引b根据b与比排序a根据索引
a.sort(key=lambda x: x[0])
ind = [i[0] for i in sorted(enumerate(b),key=lambda x: x[1])]
a = [i[0] for i in sorted(zip(a,ind),key=lambda x: x[1])]
since every sorting takes n*log(n) this is still scalable for bigger lists
由于每次排序都需要 n*log(n) 这对于更大的列表仍然是可扩展的
回答by pylang
Traditional sorting may not be needed.
可能不需要传统的排序。
[tup for lbl in b for tup in a if tup[0] == lbl]
# [('ec', 3), ('ax', 1), ('bk', 5)]
回答by Aran-Fey
There's actually a way to do this in linear O(n) time, because this isn't really a sorting operation. The existence of the list bmeans that the sorting is already done; all we really need to do is to rearrange the elements of ato be in the same order. This can be done efficiently thanks to dictionaries.
实际上有一种方法可以在线性 O(n) 时间内做到这一点,因为这并不是真正的排序操作。列表的存在b意味着排序已经完成;我们真正需要做的就是a按照相同的顺序重新排列 to 的元素。由于字典,这可以有效地完成。
from collections import defaultdict
def sorted_by(seq_to_sort, desired_order, key=None):
if key is None:
key = lambda x: x
# group the elements by their key
grouped_items = defaultdict(list)
for item in seq_to_sort:
k = key(item)
grouped_items[k].append(item)
# flatten the dict of groups to a list
return [item for key in desired_order for item in grouped_items[key]]
Usage:
用法:
a = [("ax", 1), ("ec", 3), ("bk", 5)]
b = ["ec", "ax", "bk"]
result = sorted_by(a, b, lambda tup: tup[0])
print(result) # output: [("ec", 3), ("ax", 1), ("bk", 5)]
Notes:
笔记:
This is a stable sort; if two list items have the same key, their order will be preserved. Example:
>>> sorted_by([1, 2, 3], [5], key=lambda x: 5) [1, 2, 3]If any list elements are mapped to keys that don't exist in
desired_order, those elements are silently discarded. For example:>>> sorted_by([1, 2, 3], [1, 2, 3], key=lambda x: 5) []
这是一种稳定的排序;如果两个列表项具有相同的键,则它们的顺序将被保留。例子:
>>> sorted_by([1, 2, 3], [5], key=lambda x: 5) [1, 2, 3]如果任何列表元素映射到 中不存在的键,则
desired_order这些元素将被静默丢弃。例如:>>> sorted_by([1, 2, 3], [1, 2, 3], key=lambda x: 5) []
See also:
也可以看看:

