在Python中将txt文件解析为字典

-1 投票
4 回答
1401 浏览
提问于 2025-04-18 10:04

关于在Python中解析文本文件的帖子有很多,但我遇到了一种特殊情况,我的txt文件并不是总是那么整齐。

在理想的情况下,键和值会在同一行用等号分开,这样你就可以逐行读取并把值存储到一个字典里。但显然,这个世界并不完美。以下是我txt文件的一部分:

Map ID  = 
26
Device Type = iPhone OS
Tutorial viewed = false
Last 5 errors = (
    142,
    752,
    142,
    752,
    752
)

IP of Device     = XXX.XX.XXX.XX

在保持内容在同一行方面,它非常不一致。例如,有时候

Device Type = iPhone OS

有时候

Device Type = iPhone
OS

还有时候

Device Type = 
iPhone OS

我该如何处理这些文件,以便无论格式多糟糕,都能得到一个类似下面代码的字典呢:

{'Map ID': 26,
 'Device Type': iPhone OS,
 'Tutorial viewed': false,
 'Last 5 errors': {142, 752, 142, 752, 752},
 'IP of Device': XXX.XX.XXX.XX}

此外,txt文件中还有很多行不包含等号,有些需要被忽略,有些则是用冒号(:)分隔的,但这又是另一个话题。

4 个回答

0

我不知道你文件的其他部分长什么样,但这个可能有效:

d = {}
key = None
value = ''
with open(infile) as fin:
    for line in fin:
        if '=' in line:  # New key starting.
            if key:
                d[key] = value
            value = ''  # Reset.
            key = line.split('=')[0].strip()
            value += line.split('=')[1].strip()

        else:  # Only additional value in line.
            value += line.strip() 

很遗憾我还不能评论,不过你说得对,我改了字典的名字。

0

我认为,你需要在聚合(合并)行的时候,确保只遇到一个“=”符号,因为这可能是你最好的分隔符。解析错误元组(错误信息)成一个集合,或者把“false”字符串转成布尔值(真或假)的逻辑,就要看你怎么实现了,但别忘了在初步解析后去掉换行符。下面是一段代码示例:

initial split = myText.split("=")
firstKey = split[0]
secondSplit = split[1].split(\n)
firstVal = secondSplit[:-1]
secondKey = secondSplit[-1]

这只是一个例子,并不是普遍适用的规则。你需要自己想出逻辑,把第一部分和最后一部分当作特殊情况处理,而中间的部分基本上是一样的。

2

假设分隔符(在这个例子中是'=')永远不会出现在数据值中,我会这样做:

mydict = {}
key, val = None, ''
for line in dirty_file:
    if '=' in line:
        if key is not None:
            mydict[key] = val  # You might want to do type conversions here
        key, val = line.strip().split('=')
    else:
        val += line.strip()

if key is not None:  # For the final item
    mydict[key] = val
5

假设每个键(key)总是在等号(=)的同一行上,你可以逐行查看这些内容。如果这一行是一个“键”行,就添加一个新的条目;如果不是,就把内容加到最后一个键的条目里。

d = {}
for line in infile:
    if "=" in line:
        key, val = map(str.strip, line.split("="))
        d[key] = val
    else:
        d[key] += line.strip()

另外,= 在值(value)中是绝对不能出现的。你给出的例子的输出结果是:

{'IP of Device': 'XXX.XX.XXX.XX', 'Device Type': 'iPhone OS', 'Map ID': '26', 
 'Tutorial viewed': 'false', 'Last 5 errors': '(142,752,142,752,752)'}

撰写回答