繁体   English   中英

如何根据另一个列表对元组列表进行排序

[英]How to sort a list of tuples according to another list

有一个列表:

a = [("ax", 1), ("ec", 3), ("bk", 5)]

另一个清单:

b = ["ec", "ax", "bk"]

我想根据ba进行排序:

sort_it(a, b)

a = [("ec", 3), ("ax", 1), ("bk", 5)]

这个怎么做?

a.sort(key=lambda x: b.index(x[0]))

此排序a利用在索引就地b每个元组的第一个元素的从a因为它排序上的值。

另一种可能更简洁的写法是:

a.sort(key=lambda (x,y): b.index(x))

如果你有大量的项目,做一些不同的事情可能会更有效,因为.index()可能是一个长列表上的昂贵操作,你实际上不需要做一个完整的排序,因为你已经知道顺序:

mapping = dict(a)
a[:] = [(x,mapping[x]) for x in b]

请注意,这仅适用于 2 元组列表。 如果您希望它适用于任意长度的元组,则需要稍微修改它:

mapping = dict((x[0], x[1:]) for x in a)
a[:] = [(x,) + mapping[x] for x in b]

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

由于每次排序都需要 n*log(n) 这对于更大的列表仍然是可扩展的

实际上有一种方法可以在线性 O(n) 时间内做到这一点,因为这并不是真正的排序操作。 列表b的存在意味着排序已经完成; 我们真正需要做的就是将a的元素重新排列为相同的顺序。 这可以通过字典有效地完成。

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]]

用法:

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)]

笔记:

  • 这是一种稳定的排序; 如果两个列表项具有相同的键,则它们的顺序将被保留。 例子:

     >>> 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) []

也可以看看:

可能不需要传统的排序。

[tup for lbl in b for tup in a if tup[0] == lbl]
# [('ec', 3), ('ax', 1), ('bk', 5)]

暂无
暂无

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

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