How to rearrange one list based on a second list of indices
本问题已经有最佳答案,请猛点这里访问。
我有一个10个项目的列表,还有一个10个随机不重复的数字列表,如下所示:
1 2 | l = [a,b,c,d,e,f,g,h,i,j] m = [1,4,5,9,2,6,3,7,8,10] |
我想重新排列
例如,
我对算法很在行,逻辑也让我抓狂,所以我不知道该如何处理这个问题。
我该怎么做?
如果您只是想让元素根据其他列表位置移动,那么可以循环遍历EDOCX1的所有元素(0),并使用列表理解来获取EDOCX1的元素(1)
1 | l2 = [l[i - 1] for i in m] |
但是,如果您希望基于其他列表进行排序,则需要将它们压缩在一起,对索引进行排序,然后提取元素
1 | [y for x,y in sorted(zip(m,l))] |
号
注:我假设
如果是这样,你可以很容易地得到你想要的,使用列表理解,
让我们一步一步来:
1 2 | >>> l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] >>> m = [1, 4, 5, 9, 2, 6, 3, 7, 8, 10] |
1 2 | >>> zip(m, l) [(1, 'a'), (4, 'b'), (5, 'c'), (9, 'd'), (2, 'e'), (6, 'f'), (3, 'g'), (7, 'h'), (8, 'i'), (10, 'j')] |
。
1 2 | >>> sorted(zip(m, l)) [(1, 'a'), (2, 'e'), (3, 'g'), (4, 'b'), (5, 'c'), (6, 'f'), (7, 'h'), (8, 'i'), (9, 'd'), (10, 'j')] |
最后,列表理解只需要从每对列表中提取第二项:
1 2 | >>> [x for i, x in sorted(zip(m, l))] ['a', 'e', 'g', 'b', 'c', 'f', 'h', 'i', 'd', 'j'] |
。
这可以在线性O(n)时间内通过听写完成:
1 2 3 4 5 6 7 8 | l = ['a','b','c','d','e','f','g','h','i','j'] m = [ 1, 4, 5, 9, 2, 6, 3, 7, 8, 10] values_by_index = dict(zip(m, l)) result = [values_by_index[index+1] for index in range(len(m))] print(result) # output: ['a', 'e', 'g', 'b', 'c', 'f', 'h', 'i', 'd', 'j'] |
。
第一行创建将索引映射到值的dict,如下所示:
1 2 | >>> values_by_index {1: 'a', 4: 'b', 5: 'c', 9: 'd', 2: 'e', 6: 'f', 3: 'g', 7: 'h', 8: 'i', 10: 'j'} |
在第二行中,我们简单地循环索引1到10,并从dict中获取相应的值,这是平均情况下的O(1)操作。
如果有基于0的索引,只需从