0

我有以下格式的字符串:

"2A:xxx\r\n3A:yyyy\r\n51:yzzzz\r\n52:yzyeys\r\n4A:....."

这需要通过在 \r\n 处拆分来转换成字典。
然而,困难的部分是,对于 3A 和 4A 之间的对,密钥需要预先添加 3A,以表明它们是 3A 的子集。
所以最终的预期输出如下:

{'2A':'xxxx','3A':'yyyy','3A-51':'yzzzz','3A-52':'yzyeys','4A':'.....}

有没有比将所有数据提取到字典中并稍后使用 for 循环遍历字典更简单的方法。这可以在单个解析过程中完成吗?

4

4 回答 4

1

str.splitlines()为您完成大部分工作:

>>> "2A:xxx\r\n3A:yyyy\r\n51:yzzzz\r\n52:yzyeys\r\n4A:.....".splitlines()
['2A:xxx', '3A:yyyy', '51:yzzzz', '52:yzyeys', '4A:.....']

这里的棘手之处在于跟踪3A密钥。大概是A定义层次结构的键中的。

最好将其拆分为生成器:

def hierarchy_key_values(lines):
    parent = ''
    for line in lines:
        key, value = line.split(':', 1)
        if key[-1] == 'A':
            parent = key + '-'
        else:
            key = parent + key

        yield key, value

剩下的很简单:

your_dict = dict(hierarchy_key_values(input_text.splitlines()))

使用您的示例输入进行演示:

>>> dict(hierarchy_key_values(input_text.splitlines()))
{'3A-52': 'yzyeys', '3A': 'yyyy', '3A-51': 'yzzzz', '2A': 'xxx', '4A': '.....'}
于 2013-05-15T15:16:52.927 回答
1

在我的头顶上:

 dct = {}
 last = ''
 for line in s.splitlines():
    key, val = line.split(':')
    if key.isdigit():
        key = last + '-' + key
     else:
        last = key
     dct[key] = val

这可行,但使用“复合”键通常不是使用分层结构的最佳方式。我会建议这样的东西:

dct = {}
last = ''
for line in s.splitlines():
    key, val = line.split(':')
    if key.isdigit():
        dct[last].setdefault('items', {})[key] = {'value': val }
    else:
        dct[key] = {'value': val }
        last = key

这使得 dict 像:

{'2A': {'value': 'xxx'},
 '3A': {'items': {'51': {'value': 'yzzzz'}, '52': {'value': 'yzyeys'}},
        'value': 'yyyy'},
 '4A': {'value': '.....'}}

看起来更复杂,但实际上它会更容易使用。

于 2013-05-15T15:16:23.710 回答
0

使用该reduce功能,您可以在迭代时保留内存,然后使用单线成功:

>>> import re
>>> reduce(lambda col, x: x + [y if re.match(r'\d+A.*', y) else col[-1][0:2] + '-' + y], s.split('\r\n'), [])
['2A:xxx', '3A:yyyy', '3A-51:yzzzz', '3A-52:yzyeys', '4A:.....']

正如 Martin 所说,该split函数将字符串拆分为多个部分,并reduce收集正在填充的集合和新元素。因此,您可以查看添加的最后一个元素 ( x[-1]) 以获取其标识符。

于 2013-05-15T15:24:08.187 回答
0
def solve(strs):
    dic = {}
    prev = None
    for x in strs.splitlines():
        key,val = x.split(":")
        if "A" not in key:                #or key.isdigit()
            new_key = "-".join((prev,key))
            dic[new_key] = val
        else:
            dic[key] = val
            prev = key
    return dic
strs = "2A:xxx\r\n3A:yyyy\r\n51:yzzzz\r\n52:yzyeys\r\n4A:"
print solve(strs)    

输出:

{'3A-52': 'yzyeys', '3A': 'yyyy', '3A-51': 'yzzzz', '2A': 'xxx', '4A': ''}
于 2013-05-15T15:30:22.250 回答