我有一个列表,说A = [[3,5],[1,3],[6,1]]
。
我还有另一个清单,比如B = [6,1,3]
我想对列表A进行排序,以便A变为[[6,1],[1,3],[3,5]]
,这符合给定的B.每个A子列表的第一个成员应按B进行排序。
答案 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)
假设A
和B
具有相同的长度,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]))