2013-07-19 85 views
2

什麼是轉換下的最佳方式:Python列表結構修飾

myList = [ 
      ['ItemB','ItemZ'], 
      ['ItemB','ItemP'], 
      ['ItemB','ItemJ','Item6'], 
      ['ItemB','ItemJ','Item5'] 
     ] 

這在Python:

newList = ['ItemB',['ItemP','ItemZ',['ItemJ',['Item5','Item6']]]] 

我能得到接近使用由萊恩排序的遞歸函數但無法找到Len按字母順序排序的好方法。任何幫助將不勝感激!

+9

請隨時分享你的*我能得到接近使用遞歸函數* –

+0

兩列看起來相同,我的眼睛。我錯過了什麼? –

+0

這是你想要的字典,朋友。 – 2rs2ts

回答

1

也許不是最優雅的方式,但是這似乎工作:

首先,我們把名單列表到使用的defaultdictsdefaultdicts一個defaultdict一本字典,又名infinitedict

myList = [['ItemB','ItemZ'],['ItemB','ItemP'],['ItemB','ItemJ','Item6'],['ItemB','ItemJ','Item5']] 

from collections import defaultdict 
infinitedict = lambda: defaultdict(infinitedict) 
dictionary = infinitedict() 
for item in myList: 
    d = dictionary 
    for i in item: 
     d = d[i] 

現在,我們可以使用遞歸函數將字典重新轉換爲樹狀列表:

def to_list(d): 
    lst = [] 
    for i in d: 
     lst.append(i) 
     if d[i]: 
      lst.append(to_list(d[i])) 
    return lst 

輸出是從您的預期輸出有點不同,但這似乎更有意義,對我說:

>>> print to_list(dictionary) 
['ItemB', ['ItemZ', 'ItemJ', ['Item6', 'Item5'], 'ItemP']] 

或者,更貼近您預期的結果(但還不是完全一樣的,順序是炒起來

def to_list(d): 
    return [[i] + [to_list(d[i])] if d[i] else i for i in d] 

輸出:

>>> print to_list(dictionary)[0] 
['ItemB', ['ItemZ', ['ItemJ', ['Item6', 'Item5']], 'ItemP']] 
+0

如果你可以把它變成'['ItemB',['ItemZ',['ItemJ',['Item6','Item5']],'ItemP']]'這就是OP想要的。 – 2rs2ts

1

到tobias_k的答案相似,但在格式你想,sorte因爲使用這個,而不是與字典中的中間步驟) d和所有。 (我認爲) 好吧,它已經過測試,現在似乎正在工作。

我們用defaultdict將路徑列表變成一棵樹,然後以defaultdict爲基礎的樹以遞歸方式變爲基於列表的排序形式。

from collections import defaultdict 

def tree(): 
    # A dict-based tree that automatically creates nodes when you access them. 
    # Note that this does not store a name for itself; it's closer to a dropdown 
    # menu than the little button you click to display the menu, or the contents 
    # of a directory rather than the directory itself. 
    return defaultdict(tree) 

def paths_to_tree(paths): 
    # Make a tree representing the menu. 
    menu = tree() 
    for path in myList: 
     add_to = menu 

     # Traverse the tree to automatically create new tree nodes. 
     for name in path: 
      add_to = add_to[name] 
    return menu 

def sort_key(item): 
    if isinstance(item, list): 
     return 1, item[0] 
    else: 
     # It's a string 
     return 0, item 

# Recursively turn the tree into nested lists. 
def tree_to_lists(menu): 
    lists = [[item, tree_to_lists(menu[item])] if menu[item] else item 
      for item in menu] 
    lists.sort(key=sort_key) 
    return lists 

# Note the [0]. 
output = tree_to_lists(paths_to_tree(myList))[0]