使用python中的第一次出现进行分组排序?

时间:2013-12-08 18:46:15

标签: python algorithm list sorting

在python中,我有一个类列表,其中包含一个名为category的字符串字段。 让我们考虑以下示例:

mylist[0].category # = "furniture"
mylist[1].category # = "car"
mylist[2].category # = "fruit"
mylist[3].category # = "car"
mylist[4].category # = "furniture"

我的问题是:如何通过使用新类别的第一次出现进行分组来重新排序列表?

使用前面的示例,结果将是:

mylist[0].category # = "furniture"
mylist[1].category # = "furniture"
mylist[2].category # = "car"
mylist[3].category # = "car"
mylist[4].category # = "fruit"

4 个答案:

答案 0 :(得分:2)

首先,按照与my_list相同的顺序获取类别列表。然后,根据类别列表中每个项目类别的首次出现位置对my_list进行排序。

categories = [item.category for item in my_list]
my_list.sort(key = lambda item: categories.index(item.category))

答案 1 :(得分:1)

# create a first-appearance index
order = {}
for ndx,item in enumerate(mylist):
    if item.category not in order:
        order[item.category] = ndx

# sort by that index
mylist.sort(key=lambda i: order[i])

答案 2 :(得分:0)

您可以通过遍历列表两次(无排序)来实现此目的:

from collections import defaultdict

# put all the items of the same category together
l = defaultdict( list )
for x in mylist:
    l[ x.category ].append( x )

# expand in the order categories appear in the list
xs = [ ]
for x in mylist:
    xs.extend( l[ x.category ] )
    l.pop( x.category )

答案 3 :(得分:0)

也许是这样的?

#!/usr/local/cpython-3.3/bin/python

import pprint


CATEGORY_FIRST_SEEN = {}


def extract_order(list_of_class):
    for index, element in enumerate(list_of_class):
        if element.category not in CATEGORY_FIRST_SEEN:
            CATEGORY_FIRST_SEEN[element.category] = index

    #pprint.pprint(CATEGORY_FIRST_SEEN)


class Class_with_category:
    def __init__(self, category):
        self.category = category

    def __cmp__(self, other):
        if CATEGORY_FIRST_SEEN[self.category] < CATEGORY_FIRST_SEEN[other.category]:
            return -1
        elif CATEGORY_FIRST_SEEN[self.category] > CATEGORY_FIRST_SEEN[other.category]:
            return 1
        else:
            return 0

    def __lt__(self, other):
        return self.__cmp__(other) < 0

    def __str__(self):
        return self.category

    __repr__ = __str__


def main():
    mylist = [ "furniture", "car", "fruit", "car", "furniture", ]
    list_of_class = [ Class_with_category(element) for element in mylist ]
    extract_order(list_of_class)
    list_of_class.sort()
    pprint.pprint(list_of_class)


main()

我已经测试过它可以在cpython 3.3上运行,但我相信它应该在2.x或3.x上运行。