如何对列表中的元素进行稳定的就地相对重新排序

时间:2014-01-17 10:37:01

标签: python-3.x

我有这个功能:

def relative_reorder(my_list, before, after):
    backup_of_my_list = list(my_list)
    def my_key(item):
        if item is after:
            return backup_of_my_list.index(before) * 2 + 1
        else:
            return backup_of_my_list.index(item) * 2
    my_list.sort(key=my_key)

可以这样使用:

stack = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]
relative_reorder(stack, 9, 7)
print(stack)
[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 9, 9, 8, 8]

但我想提高分类稳定性

我会考虑这些产品更可取:

[1, 2, 3, 4, 5, 6, 8, 9, 1, 2, 3, 4, 5, 6, 8, 9, 7 ,7]
[1, 2, 3, 4, 5, 6, 9, 9, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]

目标是重新排序列表,以便所有出现的9的索引都低于所有出现的7,同时在列表中保持尽可能多的稳定性。一个用途可能是订购一些可能需要运行的任务,我们知道某个任务应该总是在另一个任务之前运行......

1 个答案:

答案 0 :(得分:0)

def last_index(l, value):
    """
    Find the last occurance of value in the list
    """
    # http://stackoverflow.com/q/522372/693869#comment336488_522401
    return len(l) - 1 - l[::-1].index(value)

def move_item(l, old, new):
    """
    Move an item from an old index to a new index
    """
    l.insert(new, l.pop(old))

def relative_reorder(l, before, after):
    """
    reorder list so that all occurrences of before are of a lower 
    index than all occurrences of after
    """
    while last_index(l, before) > l.index(after):
        move_item(l, last_index(l, before), l.index(after))

stack = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]
relative_reorder(stack, 9, 7)
print(stack)
[1, 2, 3, 4, 5, 6, 9, 9, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]

如果有人有更清洁的版本,请接受