2013-02-21 173 views
1

我有一個描述層次,因爲這樣的名單:通過嵌套列表排序

[obj1, obj2, [child1, child2, [gchild1, gchild2]] onemoreobject]

其中,child1(和其他人)是obj2的孩子,而gchild1和2子2兒童

例如,這些對象的每個屬性都有像date這樣的屬性,我想根據這些屬性對它們進行排序。在常規的名單我會是這樣的:

sorted(obj_list, key=attrgetter('date'))

在這種情況下,仍然該方法不會工作,因爲名單沒有date屬性......即使做到了,如果它的屬性是不同的的父級,那麼等級順序將被打破。有沒有一種簡單而優雅的方式來在Python中做到這一點?

+1

這看起來像它將是樹結構的完美數據集。 – Serdalis 2013-02-21 03:38:47

+0

你能提供所需的輸出嗎?您是否想按字典順序排列列表,同時保持層次結構?即,[obj2,obj1,[child1,child2,[gchild1,gchild2]] onemoreobject]'將排序到[obj1,[child1,child2,[gchild1,gchild2]],obj2,onemoreobject] – dawg 2013-02-21 16:59:40

+0

如上所述,所需的輸出將取決於名爲'date'的對象屬性。你的例子是有效的,如果日期將以這樣的方式安排,但我絕不打算根據對象名稱進行排序。所以如果'obj1.date'第二次行進而'obj2.date'第一次行進,這部分列表應該看起來像這樣: '[obj2,[child1,child2,[gchild1,gchild2]],obj1 ]' – user2016907 2013-02-22 02:01:58

回答

-1

如果你想不考慮那些不是同級節點一個節點的所有兒童進行排序,去一個樹型結構:

class Tree: 
    def __init__ (self, payload): 
     self.payload = payload 
     self.__children = [] 

    def __iadd__ (self, child): 
     self.__children.append (child) 
     return self 

    def sort (self, attr): 
     self.__children = sorted (self.__children, key = lambda x: getattr (x.payload, attr)) 
     for child in self.__children: child.sort (attr) 

    def __repr__ (self): 
     return '{}: {}'.format (self.payload, self.__children) 
+0

我認爲這個答案會在這部分問題上發生變化:「如果它的屬性與其父類不同,那麼等級順序將被打破」。 – Marius 2013-02-21 03:53:36

+0

我不明白這部分的問題。你能向我解釋它的含義嗎? – Hyperboreus 2013-02-21 03:54:20

+0

他是否想根據屬性對每個節點的子節點進行排序,而不考慮其餘節點? – Hyperboreus 2013-02-21 03:55:32

0

我認爲你需要把你的鑰匙在排序(鍵=無)功能,這將工作。我用字符串測試它,它似乎工作。我不確定一個對象的結構。這是以obj1和obj2排序的。我認爲一個對象可能代表一個新的層次結構,因此我將每個層次結構都包含在一個列表中,以便將對象保持在一起。

def embededsort(alist): 
    islist = False 
    temp = [] 
    for index, obj in enumerate(alist): 
    if isinstance(obj,list): 
     islist = True 
     embededsort(obj) 
     temp.append((index,obj)) 
    if islist: 
    for lists in reversed(temp): 
     del alist[lists[0]] 
    alist.sort(key=None) 
    for lists in temp: 
     alist.append(lists[1]) 
    else: 
    alist.sort(key=None) 
    return alist 

>>>l=[['obj2', 'obj1', ['child2', 'child1', ['gchild2', 'gchild1']]], ['obj22', 'obj21', ['child22', 'child21', ['gchild22', 'gchild21']]]] 
>>>print(embededsort(l)) 
[['obj1', 'obj2', ['child1', 'child2', ['gchild1', 'gchild2']]], ['obj21', 'obj22', ['child21', 'child22', ['gchild21', 'gchild22']]]] 
0

這是使用Python提供的多態性的QuickSort算法的實現。它應該爲整數,浮點數,列表,嵌套的列表,元組,甚至字典

def qsort(list): 
    if not list: return [] 
    first = list[0] 
    lesser = filter(lambda x: x < first, list[1:]) 
    greater = filter(lambda x: x >= first, list[1:]) 
    return qsort(lesser) + [first] + qsort(greater) 
+0

工作在一個單子列表上,但在我的嵌套列表中仍然有: 'AttributeError:'list'object has no attribute'date'' – user2016907 2013-02-21 16:55:21

0

感謝您的答案,因爲他們給了我不少的想法,新的東西可以借鑑。最終的代碼看起來像這樣。不像我想象的那樣舒適和優雅,但作品:

def sort_by_date(element_list): 
    last_item = None 
    sorted_list = [] 
    for item in element_list: 
     #if item is a list recurse and store it right below last item (parent) 
     if type(item) == list: 
      if last_comparisson: 
       if last_comparisson == 'greater': 
        sorted_list.append(sort_by_date(item)) 
       else: 
        sorted_list.insert(1, sort_by_date(item)) 
     #if not a list check if it is greater or smaller then last comparisson 
     else: 
      if last_item == None or item.date > last_item: 
       last_comparisson = 'greater' 
       sorted_list.append(item) 
      else: 
       last_comparisson = 'smaller' 
       sorted_list.insert(0, item) 
      last_item = item.date 
    return(sorted_list)