【问题标题】:convert a list of delimited strings to a tree/nested dict, using python使用 python 将分隔字符串列表转换为树/嵌套字典
【发布时间】:2013-05-08 23:56:27
【问题描述】:

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

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

进入一棵树(嵌套列表或字典 - 任何易于遍历的内容)。 真实数据恰好有 1 到 4 个不同长度的点分隔部分,总共有 2200 条记录。 我的实际目标是用这些数据填充 4 个 QComboBox 的集合,以使第一个 QComboBox 填充第一个设置项 ['one'、'five'、'twelve'](没有重复项)。然后根据所选项目,第二个 QComboBox 将填充其相关项目:对于“一个”,它将是:[“二”,“六”],依此类推,如果还有另一个嵌套级别。

到目前为止,我有一个工作列表 -> 嵌套的 dicts 解决方案,但它非常慢,因为我使用常规的 dict()。而且我似乎很难将其重新设计为默认字典,以便轻松正确地填充 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)

【问题讨论】:

    标签: python dictionary pyside defaultdict


    【解决方案1】:
    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": {}
       }
      }
     }
    }
    

    【讨论】:

    • 耶,太棒了!感谢您的快速回复。现在我只需要教它对 dicts 进行切片。
    • 您能否建议切片代码(根据所选更高级别的密钥获取一组密钥)尽可能简单?似乎我倾向于将递归放在奇怪的地方,而您的代码却因其简单而震惊了我。
    • @python_head:我不完全确定你的意思......鉴于上述结构和键one - 切片代码应该返回什么?
    • 获取字典级别的方法:level1 = [one,five,twelve];如果选择level1=one,那么level2 = [two,six];如果 level2=2,则 level3=[three],以此类推。如果为空,则返回空列表/字典。
    • @python_head: 看起来你需要dict.keys(): tree['one'].keys() 返回['six', 'two'](虽然不能保证顺序)。
    【解决方案2】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-29
      • 1970-01-01
      • 1970-01-01
      • 2016-02-08
      • 2020-05-16
      • 2021-09-25
      • 1970-01-01
      相关资源
      最近更新 更多