如何在Python中从文件中读取多个字典?

8

我是一个相对新手的Python程序员。我正在尝试读取一个包含多个字典的ASCII文件。该文件的格式如下。

{Key1: value1
 key2: value2
 ...
}
{Key1: value1
 key2: value2
 ...
}
{
...

文件中的每个字典都是一个嵌套字典。我想将它作为字典列表进行读取。是否有简单的方法可以做到这一点?我尝试了以下代码,但似乎不起作用。

data = json.load(open('doc.txt'))

2
你得到了什么错误? - Mohammad
4个回答

3

如果内部元素是有效的JSON格式,以下内容可能会起作用。我挖掘了simplejson库的原始代码并对其进行修改以适应您的使用情况。下面是一个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'}]}

运作完美,非常感谢,我真的很欣赏。 - Rahul
我在字典中有一些值是函数。例如: ' {key11: function(argument11) key12: {dict11}} {key21: function(argument12) key22: {dict21}} ' 你的代码能否扩展以读取这些字典? - Rahul
你能否给出更明确的例子?可以是真实数据的简洁版本。从key11function(argument11)来看,很难看出您原始数据的结构 - 它是否包含引号?是否包含逗号?函数需要被调用吗?您应该编辑问题并更新示例输入和输出。 - UltraInstinct

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
你需要将其放入一个大列表中才能使其正常工作。例如:
[
    {key1: val1, key2: val2, key3: val3, ...keyN: valN}
    , {key1: val1, key2: val2, key3: val3, ...keyN: valN}
    , {key1: val1, key2: val2, key3: val3, ...keyN: valN}
    .
    .
    .
]

如果您无法更改数据文件格式,恐怕您将不得不自行编写函数来解释数据。

那不会起作用。 字典之间没有逗号。 字典中的键值对之间没有逗号。 - UltraInstinct

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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接