【问题标题】:Sort list in place using another list of index使用另一个索引列表对列表进行就地排序
【发布时间】:2014-03-27 12:06:20
【问题描述】:

给定

a = [1,4,5,3,2,6,0]
b = ['b','e','f','d','c','g','a']

订单b就位,b的预期顺序在a的相应位置元素中可用。

输出将是

['a','b','c','d','e','f','g']

尝试其他类似的输入集。

a = [4,0,1,3,2]
b = ['E','A','B','D','C']

我可以使用第三个列表来完成它,即使sorted() 创建了第三个列表,但关键是对b 进行排序

print sorted(b,key=lambda bi : a[b.index(bi)])

问题的核心是如何防止对b 中已经迭代的项目进行迭代。

【问题讨论】:

  • 要就地排序,你有.sort()
  • B = dict((v, i) for i, v in enumerate(b)) 可以帮助您,如果您的列表中有独特的元素
  • 您可以同时对两个列表进行简单的冒泡排序。
  • .sort() 也接受 key 参数。
  • 别忘了 b.index(bi) 在 O(n) 中运行,这会将排序减慢到 O(n^2 log n)。这比冒泡排序更糟糕。另外,如果a 包含重复项,它也不起作用。

标签: python algorithm list sorting


【解决方案1】:

试试这个:

zip(*sorted(zip(a, b)))[1]

应该给:

('a', 'b', 'c', 'd', 'e', 'f', 'g')

由于在排序过程中b 本身似乎是空的(请参阅my question about that),您可以使用那段代码就地完成:

b.sort(key=lambda x, b=b[:]: a[b.index(x)])

这使用b副本 在排序期间进行搜索。这对性能肯定不是很好,所以不要怪我;-)

【讨论】:

  • 当然,这不适用于b。所以你可能不想使用它。
  • 这很奇怪。我试了b.sort(key=lambda x: a[b.index(x)]),发现在排序过程中,b好像是一个空列表。
  • 我将此效果发布为new question
  • 没错,b在排序的时候被清空了
  • 我想讨论一下,想给点,所以请访问上面提到的Q :)
【解决方案2】:

关键是要意识到b 中的项目对key 功能没有多大用处。您对a 中的同行感兴趣。要就地执行此操作,意味着您不能只使用zip 将项目配对。在这里,我使用默认参数技巧将 a 上的迭代器放入 lambda 函数中。

>>> a = [1,4,5,3,2,6,0]
>>> b = ['b','e','f','d','c','g','a']
>>> b.sort(key=lambda x, it=iter(a): next(it))
>>> b
['a', 'b', 'c', 'd', 'e', 'f', 'g']

【讨论】:

  • .sort 是否保证键函数将按顺序调用并且每个项目仅调用一次?
  • 我强烈支持@Eric 的问题(因此有此评论)。有这样的保证吗?否则,由于排序算法的实现细节,该解决方案才有效。实际上我很惊讶关键功能只是以这种(这里很合适)的方式使用。
  • @Alfe,这是个好问题。我现在还没有时间去寻找权威的答案。也许您可以提出一个新问题并获得比我更多的受众。我也对答案感兴趣。
【解决方案3】:
def sorter(a,b):
    for i in range(len(a)):
        while i != a[i]:
            ai = a[i]
            b[i], b[ai], a[i], a[ai] = b[ai], b[i], a[ai], a[i]
    return b

【讨论】:

  • 很好,这同时订购了 a 和 b。如果我们只想做 b
  • @nr.o 我认为这是不可能的。您需要跟踪您已经排序的周期,并且由于它们的数量是 O(n),您需要那么多地方。否则,很好的解决方案 M4rtini,我花了一段时间从我的记忆中挖掘出多年来丢失的算法 101:D
【解决方案4】:

简单冒泡排序:

for i in range( len(a) ):
    for j in range(len(a)-1-i):
         if (a[j] > a[j+1]):
             #swap a[j] & a[j+1]
             #swap b[j] & b[j+1]

【讨论】:

    猜你喜欢
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2011-01-17
    • 2021-07-14
    • 2012-06-01
    • 2019-09-25
    • 1970-01-01
    相关资源
    最近更新 更多