根据另一个列表中的值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])]
解释:
-
zip
两个list
。 - 使用
sorted()
创build一个基于zip
的新的sortinglist
。 - 使用列表理解从已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')