Python 如何解析A:A:B:B:C和&x7;A:B:B:D和x7;A:B:B:D和x7;以及如何解析A:7;A:A:x 7;A:A:A:7;A:A:A:A:A:A:A:A:A:A:A:A:B如何解析;A:A:A:B如何解析;A:A:A:A:B;A:A:A:A:A:A:B;A:A:B;A:A:A:A:A:A:B;如何如何解析;A;A:A:A:A:A:A:B;如何解析;A:B;A:A:A:A:A;如何;如何;如何;如何解析;如何解析;如何解析;A;A:A:A;A;A:A:A:A;如何;如何解析;如何解析;A;如何;A:A;A:A:A;A;如何;A;A

Python 如何解析A:A:B:B:C和&x7;A:B:B:D和x7;A:B:B:D和x7;以及如何解析A:7;A:A:x 7;A:A:A:7;A:A:A:A:A:A:A:A:A:A:A:A:B如何解析;A:A:A:B如何解析;A:A:A:A:B;A:A:A:A:A:A:B;A:A:B;A:A:A:A:A:A:B;如何如何解析;A;A:A:A:A:A:A:B;如何解析;A:B;A:A:A:A:A;如何;如何;如何;如何解析;如何解析;如何解析;A;A:A:A;A;A:A:A:A;如何;如何解析;如何解析;A;如何;A:A;A:A:A;A;如何;A;A,python,parsing,data-structures,Python,Parsing,Data Structures,本质上,我需要为标记的某个产品编写一个解析器。这是一个字符串列表,格式如下: x = [ 'A:B:C:D:E', 'A:B:D', 'A:C:E:F', 'B:D:E', 'B:C', 'A:C:F', ] 我需要将其转换为python对象,如下所示: { "B": [ "C", { "D": "E" } ], "A": [ { "B": [ "D", { "C":

本质上,我需要为标记的某个产品编写一个解析器。这是一个字符串列表,格式如下:

x = [
'A:B:C:D:E',
'A:B:D',
'A:C:E:F',
'B:D:E',
'B:C',
'A:C:F',
]
我需要将其转换为python对象,如下所示:

{
  "B": [
    "C", 
    {
      "D": "E"
    }
  ], 
  "A": [
    {
      "B": [
        "D", 
        {
          "C": {
            "D": "E"
          }
        }
      ]
    }, 
    {
      "C": [
        "F", 
        {
          "E": "F"
        }
      ]
    }
  ]
}
您可以复制上面的内容并粘贴到中,以查看对象层次结构,并了解我的意图。在任何方面,它都是一个嵌套字典,结合了常用键,有时还将项目放入列表中

TL;博士 我在下面写了一个函数

splits = [l.split(':') for l in x]

def DictDrill(o):
    # list of lists
    if type(o)==type([]) and all([type(l)==type([]) for l in o]):
        d = dict()
        for group in o:
            if type(group)==type([]) and len(group)>1:
                d[group[0]] = d.get(group[0],[]) + [group[1:]]
            if type(group)==type([]) and len(group)==1:
                d[group[0]] = d.get(group[0],[]) + []
        return DictDrill(d)
    # a dictionary
    elif type(o)==type({}):
        next = dict(o)
        for k,groups in next.items():
            next[k] = DictDrill(groups)
        return next
但您将看到,此脚本仅返回字典,最后一项作为键再次放置,值为空
dict()
。如果对示例运行我的脚本,如
DictDrill(splits)
,您将看到:

{
  "B": {
    "C": {}, 
    "D": {
      "E": {}
    }
  }, 
  "A": {
    "C": {
      "E": {
        "F": {}
      }, 
      "F": {}
    }, 
    "B": {
      "C": {
        "D": {
          "E": {}
        }
      }, 
      "D": {}
    }
  }
}
请注意无用的{}作为值
最好我需要用python解决这个问题。我懂一点C#但在列表和字典之间移动数据似乎很麻烦…

您可以使用
itertools.groupby
和递归:

from itertools import groupby as gb
data = ['A:B:C:D:E', 'A:B:D', 'A:C:E:F', 'B:D:E', 'B:C', 'A:C:F']
def to_dict(d):
  if isinstance(d, dict) or not d or any(isinstance(i, (dict, list)) for i in d):
    return d
  return d[0] if len(d) == 1 else {d[0]:to_dict(d[1:])}

def group(d):
   _d = [(a, [c for _, *c in b]) for a, b in gb(sorted(d, key=lambda x:x[0]), key=lambda x:x[0])] 
   new_d =[{a:to_dict(b[0] if len(b) == 1 else group(b))} for a, b in _d]
   return [i for b in new_d for i in (b if not all(b.values()) else [b])]

输出:

[
  {
    "A": [
        {
            "B": [
                {
                    "C": {
                        "D": "E"
                    }
                },
                "D"
            ]
        },
        {
            "C": [
                {
                    "E": "F"
                },
                "F"
            ]
        }
     ]
  },
  {
    "B": [
        "C",
        {
            "D": "E"
        }
      ]
   }
]

你能详细说明层次结构是如何定义的吗?经过一点探索后,我不太清楚。你可以通过构建一个@BrianJoseph来实现这一点。所以“a:B:C”和“a:B:D”应该组合在一起,因为它们共享公共密钥。它应该首先变成{'A':['B:C','B:D']}。然后,由于公用键“B”,可以进一步组合值列表。结果是{'A':{'B':['C','D']},其中的值不再具有公共键…我所在的环境是IronPython2.7。这就是为什么它给了我一个语法错误,这一行
\ud=[(a,[c代表,*c在b中])为a,b在gb中(排序(d,key=lambda x:x[0]),key=lambda x:x[0])
。它说的是意想不到的*
[
  {
    "A": [
        {
            "B": [
                {
                    "C": {
                        "D": "E"
                    }
                },
                "D"
            ]
        },
        {
            "C": [
                {
                    "E": "F"
                },
                "F"
            ]
        }
     ]
  },
  {
    "B": [
        "C",
        {
            "D": "E"
        }
      ]
   }
]