Python根据给定的顺序对列表进行排序

时间:2017-09-22 13:06:21

标签: python list sorting

我有一个列表,说A = [[3,5],[1,3],[6,1]]

我还有另一个清单,比如B = [6,1,3]

我想对列表A进行排序,以便A变为[[6,1],[1,3],[3,5]],这符合给定的B.每个A子列表的第一个成员应按B进行排序。

5 个答案:

答案 0 :(得分:15)

派生一个dict,将B中的数字映射到它们的索引,并在排序键函数中使用它。这样可以保持键功能的恒定时间。

>>> A = [[3,5],[1,3],[6,1]]
>>> B = [6,1,3]
>>> srt = {b: i for i, b in enumerate(B)}
>>> sorted(A, key=lambda x: srt[x[0]])
[[6, 1], [1, 3], [3, 5]]

这段代码肯定有一些警告。如果在B中重复了一个数字,您将获得排序中使用的最后一个条目的索引。

如果A中的条目与B不匹配,则您有一个KeyError。你可以通过使用dict.get使用一些默认值来缓解这种情况,但是如果您的输入数据一开始就搞错了,那么错误是一件好事。

答案 1 :(得分:9)

您可以使用[0]

中的A查找.index的每个B元素所在的位置
>>> sorted(A, key = lambda i: B.index(i[0]))
[[6, 1], [1, 3], [3, 5]]

或就地排序

>>> A.sort(key = lambda i: B.index(i[0]))
>>> A
[[6, 1], [1, 3], [3, 5]]

答案 2 :(得分:3)

假设AB具有相同的长度,A中元组的每个第一个元素都对应B中的元素,并且没有重复项,你可以用这个:

>>> A = [[3,5],[1,3],[6,1]]
>>> B = [6,1,3]
>>> A_ind = {b: [b, a] for (b, a) in A}
>>> [A_ind[b] for b in B]
[[6, 1], [1, 3], [3, 5]]

这只会创建一个dict,将b部分从A映射到整个元素,并在B dict中查找相应的元素。不使用sorted而不使用index,这具有O(n)的复杂性。

如果可以是重复元素,您可以创建dict(或defaultdict)映射键到具有该键的元素列表:

>>> A = [[3,5],[1,3],[6,1],[1,4]]
>>> A_ind = collections.defaultdict(list)
>>> for b, a in A:
...     A_ind[b].append([b,a])
...     
>>> B = [6,1,3,1]
>>> [a for b in B for a in A_ind[b]]
[[6, 1], [1, 3], [1, 4], [3, 5], [1, 3], [1, 4]]

或者将list转换为iter ators,将A中的值分配到B中的匹配键:

>>> A_ind = {k: iter(v) for k, v in A_ind.items()}
>>> [next(A_ind[b]) for b in B]
[[6, 1], [1, 3], [3, 5], [1, 4]]

答案 3 :(得分:2)

这与CoryKramer的答案非常相似,但速度要快一些。而不是使用排序功能,手动将项目插入另一个列表。这样,index方法不常被调用。 (此代码假定b中的元素是不同的。)

a= [[3,5],[1,3],[6,1]]
b=[6,1,3]

c= [-1]*len(b) # dummy data

for x in a:
    c[b.index(x[0])]= x

print(c)

答案 4 :(得分:0)

sorted(A, key=lambda x: B.index(x[0]))