Python:根据其副本上的结果顺序对列表进行排序



相关问题:在最后一部分中,我正在寻找一种比嵌套的 for 循环更快的方法。

假设我们有一个列表a = [a_0, a_1, ..., a_n].我们创建了一个名为b = [b_0, b_1, ..., b_n]a深层副本,其中b_ia_i是相同的对象,但分开存储。现在我们在bsome_sort执行一定的排序算法,以获得一个排序order_b = [b'_0, b'_1, ..., b'_n]其中这些b'_i相同的对象对象b排列(由于some_sort算法是破坏性的,order_b中的元素不再与b中的元素相同,但引用保持不变)。现在,我希望a按照order_b中的相同顺序进行排序,即获得一个排序order_a = [a'_0, a'_1, ..., a'_n],它是从a排列的排列方式,就像order_bb排列一样,但我无法some_sorta执行排序算法,因为该算法是破坏性的。有没有快速的方法可以做到这一点?

示例:a = [a_0, a_1, a_2, a_3]a的深层副本b = [b_0, b_1, b_2, b_3]b上得到的排序是order_b = [b_3, b_2, b_0, b_1],那么我想要的是按照order_b获得order_a = [a_3, a_2, a_0, a_1]

import copy   
a = [2,4,3,1]
Out[94]: [2, 4, 3, 1]
#create a deep copy of a
b = copy.deepcopy(a)
Out[96]: [2, 4, 3, 1]
#add index of b and its value to a tuple
b1 = [(v,k) for k, v in enumerate(b)]
Out[98]: [(2, 0), (4, 1), (3, 2), (1, 3)]
#sort b1 (can using whatever criteria for sorting)
b1 = sorted(b1)
Out[100]: [(1, 3), (2, 0), (3, 2), (4, 1)]
#extract elements from a using the order of b1.
[a[e] for e in [e[-1] for e in b1]]
Out[101]: [1, 2, 3, 4]

你提到你在b'_i中保留了原始b_i引用,所以你可以创建一个反向查找{b_i: idx},例如(伪):

mapping = {b'_i->b_i: idx for idx, b'_i in enumerate(order_b)}
[m for m, n in sorted(zip(a,b), key=lambda x: mapping[x[1]])]

演示,获取数字和字母列表,随机化字母并按与随机字母相同的顺序返回数字:

In [1]:
import random
a = list(range(10))
b = list('abcdefghij')
b_ = random.sample(b, k=len(b))
''.join(b_)
Out[1]:
'idfehbgacj'
In [2]:
mapping = {k: idx for idx, k in enumerate(b_)}
[m for m, n in sorted(zip(a,b), key=lambda x: mapping[x[1]])]
Out[2]:
[8, 3, 5, 4, 7, 1, 6, 0, 2, 9]

我有一个简单的解决方案:

a_ = [ a[i] for i in (b.index(j) for j in b_) ]

_or_  

b_perm = [b.index(j) for j in b_ ]a_ = [ a[i] for i in b_perm ]

import random
a = list(range(10))
b = list('abcdefghij')
b_ = random.sample(b, k=len(b))
b_ = ['c', 'b', 'f', 'i', 'e', 'a', 'h', 'g', 'j', 'd']
a_ = [a[i] for i in (b.index(j) for j in b_)]
a_ = [2, 1, 5, 8, 4, 0, 7, 6, 9, 3]

最新更新