【问题标题】:Rearrange list based on key WITHOUT sorting根据键重新排列列表而不进行排序
【发布时间】:2017-06-20 12:22:30
【问题描述】:

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

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

显然,按ind 键进行排序很容易,但由于上述关于ind 值的假设,O(n) 操作会产生不必要的额外O(n*logn) 成本。

所以:

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

应该给:

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

【问题讨论】:

  • 仍在排序,但没有sorted 函数。

标签: python algorithm list data-structures


【解决方案1】:

假设您的索引是唯一的,这是一种方法。您可以初始化一个新列表,然后在正确的位置插入元素。

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)

【讨论】:

  • 该死的你打败了我,太好了。
  • 这很好,但它不考虑不同的键。虽然它可能解决了 OP 的问题 :)
  • @ReutSharabani 是的...如果 OP 真的需要密钥,我会随时支持您的解决方案。
  • 不错。您能否提出一个具有相同效果的理解?
  • @Stav 使用这种技术?从来没听说过。 :) 理解将创建元素并按顺序附加它们。我不知道列表理解中的随机插入。因此,除非您当然对第一个列表进行了预排序,否则您将无法通过理解来实现这一点!
【解决方案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

【讨论】:

  • 您应该添加一个默认参数以确保完整性!
【解决方案3】:

给你。

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)))。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-23
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    相关资源
    最近更新 更多