如何通过属性有效地对python中的对象列表进行排序

时间:2018-02-09 16:54:35

标签: python sorting oop attr

可能存在类似标题的问题,但它没有帮助。

我正在编写一本字典(英语,德语),现在的目的是按字母顺序对缓存(所有词汇对象的列表)进行排序。
vocab 的每个属性都是一个列表,其中列表中的第一个元素/单词是最重要的元素/单词,因此是用于排序的单词。

这是一个有效的最低版本:

class vocab:

    def __init__(self, english, german, context, box=0):
        """ self.eng/ger/con supposed to be lists"""
        self.eng = english
        self.ger = german
        self.con = context

    def present(self):
        return "English: {}\n\nGerman: {}\n\nExample: {}\n{}\n".format(self.eng,self.ger,self.con,"-"*20)
    #...


class dictionary:

    def __init__(self, Cache=[]):
        self.cache = Cache

    def sort_cache(self, sortby="eng"):
        """sort cache alphabetically (default = english)"""
        #list with sorted items
        #  -->item: (word used to sort, related vocObject)
        sort_cache = sorted([(getattr(voc,sortby),voc) for voc in self.cache])

        self.cache = [item[1] for item in sort_cache]

    def show_cache(self):
        """ print all vocabs from self.cache"""
        out = ""
        for voc in self.cache:
            out += voc.present()
        return out
    #...

#e.g.
voc1 = vocab(["to run"],["rennen","laufen"],["Run Forest! Run!!"])
voc2 = vocab(["to hide"],["(sich) verstecken","(etw.) verbergen"],["R u hidin sth bro?"])
voc3 = vocab(["anything"],["irgendwas"],["Anything ding ding"])
voc4 = vocab(["example","instance","sample"],["Beispiel"],["sample"])

MAIN_DIC = dictionary([voc1,voc2,voc3,voc4])

print MAIN_DIC.show_cache() #-->prints vocabs in order: to run, to hide, anything, example
                            #                           (voc1), (voc2) ,  (voc3) , (voc4)
MAIN_DIC.sort_cache()

print MAIN_DIC.show_cache() #-->prints vocabs in wanted order: anything, example, to hide, to run
                            #                                   (voc3) , (voc4) , (voc2) , (voc1)

由于我在sort_cache方法中创建了一个全新的缓存,我想知道什么是更有效的方式。我确定有一个。

例如。我认为只有在 self.cache 中对元素进行排序而不创建任何副本等更有效(节省时间)。

1 个答案:

答案 0 :(得分:4)

这是“decorate-sort-undecorate”模式:

    sort_cache = sorted([(getattr(voc,sortby),voc) for voc in self.cache])
    self.cache = [item[1] for item in sort_cache]

这是多年来在Python中进行排序的首选方法。它已被sortsorted函数中的内置支持取代:

self.cache = sorted(self.cache, key=lambda item: getattr(item, sortby))

或者

self.cache.sort(key=lambda item: getattr(item, sortby))

您可能还需要考虑按排序顺序维护self.cache(首先将事物插入正确的位置 - 请参阅bisect模块以获取帮助),从而分摊整个插入的排序成本(总体而言可能更贵,但在任何个别操作上都可能更便宜)。

另请注意:

def __init__(self, Cache=[]):

在使用此默认值的所有dictionary实例中为您提供单个 共享缓存列表。可变的默认值通常不是你想要的Python。