根据另一个列表中的值sorting列表?

我有这样的string列表:

X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"] Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1] 

使用Y中的值sortingX以获得以下输出的最短方式是什么?

  ["a", "d", "h", "b", "c", "e", "i", "f", "g"] 

具有相同“键”的元素的顺序无关紧要。 我可以诉诸构造的使用,但我很好奇,如果有一个更短的路。 有什么build议么?

最短的代码

 [x for _,x in sorted(zip(Y,X))] 

例:

 X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"] Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1] Z = [x for _,x in sorted(zip(Y,X))] print(Z) # ["a", "d", "h", "b", "c", "e", "i", "f", "g"] 

一般来说

 [x for _, x in sorted(zip(Y,X), key=lambda pair: pair[0])] 

解释:

  1. zip两个list
  2. 使用sorted()创build一个基于zip的新的sortinglist
  3. 使用列表理解从已sorting的压缩list 提取每对的第一个元素。

有关如何设置\使用key参数以及一般sorted函数的更多信息,请看看这个 。


将两个列表拉到一起,对其进行分类,然后取出你想要的部分:

 >>> yx = zip(Y, X) >>> yx [(0, 'a'), (1, 'b'), (1, 'c'), (0, 'd'), (1, 'e'), (2, 'f'), (2, 'g'), (0, 'h'), (1, 'i')] >>> yx.sort() >>> yx [(0, 'a'), (0, 'd'), (0, 'h'), (1, 'b'), (1, 'c'), (1, 'e'), (1, 'i'), (2, 'f'), (2, 'g')] >>> x_sorted = [x for y, x in yx] >>> x_sorted ['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g'] 

结合在一起得到:

 [x for y, x in sorted(zip(Y, X))] 

此外,如果你不介意使用numpy数组(或事实上已经在处理numpy数组…),这里是另一个不错的解决scheme:

 people = ['Jim', 'Pam', 'Micheal', 'Dwight'] ages = [27, 25, 4, 9] import numpy people = numpy.array(people) ages = numpy.array(ages) inds = ages.argsort() sortedPeople = people[inds] 

我在这里find它: http : //scienceoss.com/sort-one-list-by-another-list/

对我来说最明显的解决scheme是使用key关键字arg。

 >>> X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"] >>> Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1] >>> keydict = dict(zip(X, Y)) >>> X.sort(key=keydict.get) >>> X ['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g'] 

请注意,如果您关心以下情况,可以将其缩短为一行:

 >>> X.sort(key=dict(zip(X, Y)).get) 

我喜欢有一个sorting索引列表。 这样,我可以按照与源列表相同的顺序对任何列表进行sorting。 一旦你有了一个sorting索引列表,一个简单的列表理解就可以实现:

  X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"] Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1] sorted_y_idx_list = sorted(range(len(Y)),key=lambda x:Y[x]) Xs = [X[i] for i in sorted_y_idx_list ] print( "Xs:", Xs ) # prints: Xs: ["a", "d", "h", "b", "c", "e", "i", "f", "g"] 

请注意,sorting后的索引列表也可以使用numpy argsort()来获取。

另一种select,结合几个答案。

 zip(*sorted(zip(Y,X)))[1] 

zip,按第二列sorting,返回第一列。

 zip(*sorted(zip(X,Y), key=operator.itemgetter(1)))[0] 

more_itertools有一个并行sorting迭代器的工具:

 from more_itertools import sort_together sort_together([Y, X])[1] # ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')