根据列表中每个元素的键创建一个树

时间:2011-01-14 03:31:39

标签: python list tree wxpython nested

>>> s
[{'000000': [['apple', 'pear']]}, {'100000': ['good', 'bad']}, {'200000': ['yeah', 'ogg']}, {'300000': [['foo', 'foo']]}, {'310000': [['#'], ['#']]}, {'320000': ['$', ['1']]}, {'321000': [['abc', 'abc']]}, {'322000': [['#'], ['#']]}, {'400000': [['yeah', 'baby']]}]

>>> for i in s:
...     print i
...
{'000000': [['apple', 'pear']]}
{'100000': ['good', 'bad']}
{'200000': ['yeah', 'ogg']}
{'300000': [['foo', 'foo']]}
{'310000': [['#'], ['#']]}
{'320000': ['$', ['1']]}
{'321000': [['abc', 'abc']]}
{'322000': [['#'], ['#']]}
{'400000': [['yeah', 'baby']]}

我想根据列表中每个元素的键创建一个树。

结果逻辑将是:

{'000000': [['apple', 'pear']]}
    {'100000': ['good', 'bad']}
    {'200000': ['yeah', 'ogg']}
    {'300000': [['foo', 'foo']]}
        {'310000': [['#'], ['#']]}
        {'320000': ['$', ['1']]}
           {'321000': [['abc', 'abc']]}
           {'322000': [['#'], ['#']]}
    {'400000': [['yeah', 'baby']]}

也许嵌套列表可以实现这个,或者我需要树类型?

2 个答案:

答案 0 :(得分:2)

这是一种方法。我假设您可以依靠您的键来正确表示树结构(没有'310000'而不是'300000' - 这会导致问题,除非您在将它们添加到TreeCtrl时处理丢失的节点。)< / p>

我将首先重新组织数据,以便您可以按键检索每个节点的关联数据,并在每个节点中存储一些其他信息。

# original list of dicts
tree = [{'000000': [['apple', 'pear']]},
        {'100000': ['good', 'bad']},
        {'200000': ['yeah', 'ogg']},
        {'300000': [['foo', 'foo']]},
        {'310000': [['#'], ['#']]},
        {'320000': ['$', ['1']]},
        {'321000': [['abc', 'abc']]},
        {'322000': [['#'], ['#']]},
        {'400000': [['yeah', 'baby']]}]


# reorganize your data into a dict:
# {'000000': {'data':[['apple', 'pear']]},
#  '100000': {'data':['good', 'bad']}, ...
tree = dict([(item.keys()[0], {'data':item[item.keys()[0]]})
                  for item in tree])

然后通过将密钥的最后一个非零数字替换为零,然后将其填充回原始的位数,来查找每个节点的父ID。使用父ID更新每个dict:

for key in tree_dict.keys():

    parent_id = key.strip('0')[:-1].ljust(len(key), '0')

    # If it's all zeros, set it to None so we know the parent is root
    if int(parent_id) == 0:
        parent_id = None

    tree_dict[key].update({'parent':parent_id})

这使您很好地使用wx.TreeCtrl,因为每个节点现在都有对其父节点的引用:

{'000000':{'data': [['apple', 'pear']], 'parent': None},
 '100000':{'data': ['good', 'bad'], 'parent': None},
 '200000':{'data': ['yeah', 'ogg'], 'parent': None},
 '300000':{'data': [['foo', 'foo']], 'parent': None},
 '310000':{'data': [['#'], ['#']], 'parent': '300000'},
 '320000':{'data': ['$', ['1']], 'parent': '300000'},
 '321000':{'data': [['abc', 'abc']], 'parent': '320000'},
 '322000':{'data': [['#'], ['#']], 'parent': '320000'},
 '400000':{'data': [['yeah', 'baby']], 'parent': None}}

将根节点添加到wx.TreeCtrl,然后单步执行排序的 dict键,将每个项目的数据添加到TreeCtrl,但是您希望它显示。对于您添加的每个项目,使用AppendItem()或InsertItem()返回的TreeItemId再次更新其dict。如果dict中的'parent'值为None,则表示父节点应该是根节点。如果不是,请使用父值来检索父节点的TreeItemId,当您将其添加到TreeCtrl时,该节点应该已更新。

我希望这是有道理的。

答案 1 :(得分:0)

如果你只想要一个python结构,你可以使用它:

{'000000': ([['apple', 'pear']], [
  {'100000': (['good', 'bad'], )},
  {'200000': (['yeah', 'ogg'], )},
  {'300000': ([['foo', 'foo']],[
     {'310000': ([['#'], ['#']], )},
     {'320000': (['$', ['1']],[
       {'321000': ([['abc', 'abc']], )},
       {'322000': ([['#'], ['#']], )}
  ])},
  {'400000': ([['yeah', 'baby']], )}
])}

e.g。在每个键值对中存储元组作为值,以便元组的第一个元素是节点数据(例如[['apple','pear']],元组的第二个元素将是节点的后代列表。