使用python将分隔字符串列表转换为树/嵌套字典

时间:2013-05-14 15:52:50

标签: python dictionary pyside defaultdict

我正在尝试转换点分隔字符串列表,例如

['one.two.three.four', 'one.six.seven.eight', 'five.nine.ten', 'twelve.zero']

进入一个树(嵌套列表或dicts - 任何易于遍历的东西)。 实际数据恰好有1到4个不同长度的点分离部分,总共有2200个记录。 我的实际目标是用这些数据填充4个QComboBox'的集合,方式是第一个QComboBox填充第一个设置项['one','five','12'](没有重复)。然后根据所选择的项目,第二个QComboBox将填充其相关项:对于'one',它将是:['two','six'],依此类推,如果有另一个嵌套级别。

到目前为止,我有一份工作清单 - >嵌套的dicts解决方案,但它非常慢,因为我使用常规的dict()。而且我似乎很难将其重新设计为defaultdict,以便轻松地正确填充ComboBox。

我目前的代码:

def list2tree(m):
    tmp = {}
    for i in range(len(m)):
        if m.count('.') == 0:
            return m
        a = m.split('.', 1)
        try:
            tmp[a[0]].append(list2tree(a[1]))
        except (KeyError, AttributeError):
            tmp[a[0]] = list2tree(a[1])
    return tmp

main_dict = {}
i = 0
for m in methods:
    main_dict = list2tree(m)
    i += 1
    if (i % 100) == 0: print i, len(methods)
print main_dict, i, len(methods)

2 个答案:

答案 0 :(得分:17)

ls = ['one.two.three.four', 'one.six.seven.eight', 'five.nine.ten', 'twelve.zero']
tree = {}

for item in ls:
    t = tree
    for part in item.split('.'):
        t = t.setdefault(part, {})

结果:

{
 "twelve": {
  "zero": {}
 }, 
 "five": {
  "nine": {
   "ten": {}
  }
 }, 
 "one": {
  "six": {
   "seven": {
    "eight": {}
   }
  }, 
  "two": {
   "three": {
    "four": {}
   }
  }
 }
}

答案 1 :(得分:0)

虽然这超出了原始问题的范围,但一些评论提到了这种算法的一种形式,它包含了值。为此我想出了这个:

def dictionaryafy(self, in_dict):
    tree = {}
    for key, value in in_dict.items():
        t = tree
        parts = key.split(".")
        for part in parts[:-1]:
            t = t.setdefault(part, {})
        t[parts[-1]] = value
    return tree