按未排序列表中的出现顺序对列表项进行分组

时间:2015-07-09 14:11:40

标签: python sorting

测试用例:

group_ordered([1,3,2,3,6,3,1]) = [1,1,3,3,3,2,6]
group_ordered([1,2,3,4,5,6,1]) = [1,1,2,3,4,5,6]

我已经有了一些代码,但它很丑陋并且在大型列表上也可能很慢,因为对于每个独特的项目我都在查看整个列表。我提出了这个算法,但我想知道是否有更快,更清洁或更pythonic的方式我可以做到这一点:

def make_order_list(list_in):
    order_list = []
    for item in list_in:
        if item not in order_list:
            order_list.append(item)
    return order_list


def group_ordered(list_in):
    if list_in is None:
        return None
    order_list = make_order_list(list_in)
    current = 0
    for item in order_list:
        search = current + 1
        while True:
            try:
                if list_in[search] != item:
                    search += 1
                else:
                    current += 1
                    list_in[current], list_in[search] = list_in[search], list_in[current]
                    search += 1
            except IndexError:
                break
    return list_in

1 个答案:

答案 0 :(得分:6)

使用collections.OrderedDict() instance进行分组:

from collections import OrderedDict

def group_ordered(list_in):
    result = OrderedDict()
    for value in list_in:
        result.setdefault(value, []).append(value)
    return [v for group in result.values() for v in group]

因为此专用字典对象跟踪键的插入顺序,所以输出按第一次出现的组值排序。

演示:

>>> group_ordered([1,3,2,3,6,3,1])
[1, 1, 3, 3, 3, 2, 6]
>>> group_ordered([1,2,3,4,5,6,1])
[1, 1, 2, 3, 4, 5, 6]