从复杂的JSON文件中提取信息的最有效方法是什么?

时间:2017-01-06 03:50:47

标签: python json dictionary

我是Python新手,正致力于从dict文件中提取某些信息。

我有数百万个存储文本数据的JSON文件。所有JSON文件都具有类似的结构。结构方面有很多变化。对于每个JSON文件,我想从特定键中提取所有文本字符串并将它们存储为dict。

下面的

json1json2是简化示例。我一直在做的是从JSON文件中取样,分析它们,编写大量的if语句,试图包含所有可能的变体。但是,我发现它效率低下,但仍然无法包含所有场景。我想知道是否有一种使用密钥"text"来搜索和提取值的一般方法。

json1 = {
        "section": {
                   "heading":{"lvl":"A1", "text":"today"},
                   "paragraph":[
                                {"color":"green",  "text":"yesterday"},
                                {"color":"purple", "text":"tomorrow"}
                               ]
                   }
         }

json2 = {
        "paragraph":{"text":"everyday", "color": "black"}
        }

换句话说,我希望得到一个包含所有文本字符串的字典,其中包含“text”键。对于json1,我想获得{"json1":"today yesterday tomorrow"}。对于json2,我想获得{"json2":"everyday"}

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:5)

如果您不知道其他任何内容,并且您所暗示的结构可能相当随意,那么您必须访问每个节点并进行检查。这可以使用递归以通用方式实现。这是一个快速而肮脏的功能来实现它:

In [4]: def extract_text(obj, acc):
    ...:     if isinstance(obj, dict):
    ...:         for k, v in obj.items():
    ...:             if isinstance(v, (dict, list)):
    ...:                 extract_text(v, acc)
    ...:             elif k == "text":
    ...:                 acc.append(v)
    ...:     elif isinstance(obj, list):
    ...:         for item in obj:
    ...:             extract_text(item, acc)
...:       

以下是您将如何使用它:

In [5]: acc1 = []

In [6]: extract_text(json1, acc1)

In [7]: acc1
Out[7]: ['yesterday', 'tomorrow', 'today']

In [8]: acc2 = []

In [9]: extract_text(json2, acc2)

In [10]: acc2
Out[10]: ['everyday']

注意,您的问题与JSON没有任何关系,JSON是一种基于文本的数据序列化格式。您已经在处理反序列化数据和python数据结构。无论如何,如果你真的想要你在问题中得到的结果,你可以简单地做:

In [11]: {"json1": ",".join(acc1)}
Out[11]: {'json1': 'yesterday,tomorrow,today'}

或者您喜欢加入的任何分隔符,例如简单的空格:

In [12]: {"json1": " ".join(acc1)}
Out[12]: {'json1': 'yesterday tomorrow today'}

答案 1 :(得分:0)

如果您对json文件的结构一无所知,我建议转储内容并在列表中搜索。快速解决方案如下。它仅假定'text'键对应于单字条目。

import pickle
import json

# Open .json file
f = open("myjson.json")
# Load the content
info = json.load(f)
# Dump the content as a list of words
info_list = pickle.dumps(info).split('\n')
# Whenever you see a 'text', collect the second next item
texts = [info_list[i+2][1:] for i,a in enumerate(info_list) if a.find('text')>0]
# Output the result
print texts

每个json文件的输出变为:

In [1]: texts
Out[1]: ['yesterday', 'tomorrow', 'today']