重新排列基于键的列表WITHOUT排序

时间:2017-06-20 12:22:30

标签: python algorithm list data-structures

我有一个元组列表(x, ind),其中x是项目,ind是结果列表中的目标索引。该列表是随机顺序,但可以假设如果列表中有N项,则元组中ind的值将在[0,N)中不重复(即全部有效的指数将只存在一次)。如何获得每个元组位置为ind的列表?

请不要混淆如何按键排序的许多现有答案。

显然,按ind键排序很容易,但由于前面提到{{1}的假设,因此O(n*logn)操作应该有不必要的额外费用O(n)值。

所以:

ind

应该给:

l = [('item1',1), ('item0',0), ('item2',2), ('item4',4), ('item3',3)]
l2 = magic_rearrange(l, key=lambda x: x[1])
print(l2)

3 个答案:

答案 0 :(得分:5)

假设您的指数是唯一的,这是一种方式。您可以初始化一个新列表,只需在正确的位置插入元素。

def magic_rearrange(l1):
    l2 = [None] * len(l1)
    for i in l1:
        l2[i[1]] = i
    return l2

一个演示:

>>> l = [('item1',1), ('item0',0), ('item2',2), ('item4',4), ('item3',3)]
>>> magic_rearrange(l)
[('item0', 0), ('item1', 1), ('item2', 2), ('item3', 3), ('item4', 4)]

如果您使用numpy的花哨索引,可以更快地完成此操作。

import numpy as np
def magic_rearrange(l1):
    l2 = np.repeat(None, len(l1))
    l2[[x[1] for x in l1]] = l1
    return l2

一个演示:

>>> magic_rearrange(l)
array([('item0', 0), ('item1', 1), ('item2', 2), ('item3', 3), ('item4', 4)], dtype=object)

答案 1 :(得分:2)

首先创建列表,然后替换:

def magic_rearrange(l, key):
   # creates list to not change original list
   new_list = list(l)
   # reorder on new list
   for original_index, new_index in enumerate(map(key, l)):
       new_list[new_index] = l[original_index]
   return new_list

答案 2 :(得分:0)

你走了。

def magic_rearrange (input_list, key = lambda x: x):
    result_list = [None] * len (input_list)
    for p in input_list:
        result_list[key (p)] = p
    return result_list

我们只创建一个所需长度的列表,然后将每个元素放在其位置。 操作顺序可以是任意的,但每个元素最终都会到达结果列表中的位置。 如果复制单个列表元素并且获得密钥都是O(1),则这是O(N)。 key = lambda x: x用于默认顺序,即比较整个元素(但无用,因为结果只是list(range(N)))。