我对python比较陌生。 我正在尝试读取包含多个词典的ascii文件。该文件具有以下格式。
{Key1: value1
key2: value2
...
}
{Key1: value1
key2: value2
...
}
{
...
文件中的每个字典都是嵌套字典。 我试图将其作为词典列表阅读。有没有简单的方法来做到这一点? 我已经尝试了以下代码,但它似乎无法正常工作
data = json.load(open('doc.txt'))
答案 0 :(得分:2)
由于输入文件中的数据实际上不是JSON或Python对象文字格式,因此您需要自己解析它。您还没有真正指定字典中允许的键和值是什么,因此以下内容仅允许它们是字母数字字符串。
所以给定一个输入文件,其中包含名为doc.txt
的以下内容:
{key1: value1
key2: value2
key3: value3
}
{key4: value4
key5: value5
}
以下内容将其读取并转换为由字母数字键和值组成的字典的Python列表:
from pprint import pprint
import re
dictpat = r'\{((?:\s*\w+\s*:\s*\w+\s*)+)\}' # note non-capturing (?:) inner group
itempat = r'(\s*(\w+)\s*:\s*(\w+)\s*)' # which is captured in this expr
with open('doc.txt') as f:
lod = [{group[1]:group[2] for group in re.findall(itempat, items)}
for items in re.findall(dictpat, f.read())]
pprint(lod)
输出:
[{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'},
{'key4': 'value4', 'key5': 'value5'}]
答案 1 :(得分:1)
你必须把它放在一个大的列表中才能使它工作。即。
[
{key1: val1, key2: val2, key3: val3, ...keyN: valN}
, {key1: val1, key2: val2, key3: val3, ...keyN: valN}
, {key1: val1, key2: val2, key3: val3, ...keyN: valN}
.
.
.
]
如果您无法更改数据文件格式,我担心您必须使用自己的功能来解释数据。
答案 2 :(得分:1)
如果内部元素是有效的JSON,则以下内容可以正常工作。我挖出source of simplejson
library并修改它以适合您的使用案例。 SSCCE在下面。
import re
import simplejson
FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL
WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)
def grabJSON(s):
"""Takes the largest bite of JSON from the string.
Returns (object_parsed, remaining_string)
"""
decoder = simplejson.JSONDecoder()
obj, end = decoder.raw_decode(s)
end = WHITESPACE.match(s, end).end()
return obj, s[end:]
def main():
with open("out.txt") as f:
s = f.read()
while True:
obj, remaining = grabJSON(s)
print ">", obj
s = remaining
if not remaining.strip():
break
..在out.txt中有一些类似的JSON会输出类似的东西:
> {'hello': ['world', 'hell', {'test': 'haha'}]}
> {'hello': ['world', 'hell', {'test': 'haha'}]}
> {'hello': ['world', 'hell', {'test': 'haha'}]}
答案 3 :(得分:0)
import re
fl = open('doc.txt', 'rb')
result = map(
lambda part: dict(
re.match(
r'^\s*(.*?)\s*:\s*(.*?)\s*$', # splits with ':' ignoring space symbols
line
).groups()
for line in part.strip().split('\n') # splits with '\n', new line is a new key-value
),
re.findall(
r'\{(.*?)\}', # inside of { ... }
fl.read(),
flags=re.DOTALL # considering '\n'-symbols
)
)
fl.close()