Sorting list based on values from another list?
我有一个这样的字符串列表:
1 2 | X = ["a","b","c","d","e","f","g","h","i"] Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1] |
使用y中的值对x进行排序以获得以下输出的最短方法是什么?
1 | ["a","d","h","b","c","e","i","f","g"] |
具有相同"键"的元素的顺序无关紧要。我可以使用
短码
1 | [x for _,x in sorted(zip(Y,X))] |
Example:
ZZU1
一般性讲话
1 | [x for _, x in sorted(zip(Y,X), key=lambda pair: pair[0])] |
解释:
关于如何使用
把两张名单合起来,抽出来,然后拿走你想要的部分:
1 2 3 4 5 6 7 8 9 | >>> 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'] |
Combinee these together to get:
1 | [x for y, x in sorted(zip(Y, X))] |
此外,如果你不考虑使用numpy arrays(或事实上,already are dealing with numpy arrays…),这是另一个很好的解决办法:
1 2 3 4 5 6 7 8 | 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] |
我发现了http://scienceoss.com/sort-one-list-by-another-list/。
最明显的解决办法是用
1 2 3 4 5 6 | >>> 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'] |
注:如果你在乎:
1 | >>> X.sort(key=dict(zip(X, Y)).get) |
我喜欢有各种线索的清单。这样,我就可以把任何列表按原始列表顺序排列。一旦你有了一份各类线索的清单,一份简单的清单会做作弊:
1 2 3 4 5 6 7 8 | 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"] |
注:各种索引列表也可以使用Numpy Argorte()。
另一种选择,组合几种答案。
1 | zip(*sorted(zip(Y,X)))[1] |
In order to work for Python3:
1 | list(zip(*sorted(zip(B,A))))[1] |
事实上,我来到这里,想通过一份清单,列出价值匹配的地方。
1 2 3 4 | list_a = ['foo', 'bar', 'baz'] list_b = ['baz', 'bar', 'foo'] sorted(list_b, key=lambda x: list_a.index(x)) # ['foo', 'bar', 'baz'] |
有一个工具可用于平行输出:
1 2 3 4 | from more_itertools import sort_together sort_together([Y, X])[1] # ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g') |
拉链,从第二根柱抽出,返回第一根柱。
1 | zip(*sorted(zip(X,Y), key=operator.itemgetter(1)))[0] |
一条快线
1 2 | list_a = [5,4,3,2,1] list_b = [1,1.5,1.75,2,3,3.5,3.75,4,5] |
说你想列一张比赛名单
1 | orderedList = sorted(list_a, key=lambda x: list_b.index(x)) |
这是当需要订购一份小清单,以便在广告中增值时的帮助。假设广告名单包含小名单中的所有价值,就可以做到这一点。
我创建了一个更广泛的功能,比基于另一个单元的两个列表更有意义,受@whatang's answer的启发。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def parallel_sort(*lists): """ Sorts the given lists, based on the first one. :param lists: lists to be sorted :return: a tuple containing the sorted lists """ # Create the initially empty lists to later store the sorted items sorted_lists = tuple([] for _ in range(len(lists))) # Unpack the lists, sort them, zip them and iterate over them for t in sorted(zip(*lists)): # list items are now sorted based on the first list for i, item in enumerate(t): # for each item... sorted_lists[i].append(item) # ...store it in the appropriate list return sorted_lists |
你可以创建一个
1 2 | import pandas as pd pd.Series(data=X,index=Y).sort_index().tolist() |
输出
1 | ['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g'] |
如果你想同时得到各种名单(Python3),这就是你的答案。
1 2 3 4 5 6 7 | X = ["a","b","c","d","e","f","g","h","i"] Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1] Zx, Zy = zip(*[(x, y) for x, y in sorted(zip(Y, X))]) print(list(Zx)) # [0, 0, 0, 1, 1, 1, 1, 2, 2] print(list(Zy)) # ['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g'] |
记住ZX和Zy是双胞胎。如果有更好的方法去做,我也很想知道。
警告:如果你用空隙列表运行它。
1 2 3 4 5 | list1 = ['a','b','c','d','e','f','g','h','i'] list2 = [0,1,1,0,1,2,2,0,1] output=[] cur_loclist = [] |
获得
1 | list_set = set(list2) |
在EDOCX1&13中找到索引的位置
1 | list_str = ''.join(str(s) for s in list2) |
指数在EDOCX1&13中的位置
[0、3、7、1、2、4、8、5、6]
1 2 3 4 5 6 7 8 9 10 11 12 | for i in list_set: cur_loc = list_str.find(str(i)) while cur_loc >= 0: cur_loclist.append(cur_loc) cur_loc = list_str.find(str(i),cur_loc+1) print(cur_loclist) for i in range(0,len(cur_loclist)): output.append(list1[cur_loclist[i]]) print(output) |