2013-07-19 47 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]