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"
}
]
}
]