如何合并JSON文件中的文本

时间:2016-06-09 05:07:29

标签: python json

我拥有的是这样的:

 {
  "locale": "WORLD",
  "articles": [

    {
        "url": "Second url"
    },
    {
        "url": "Second url"       
    }
]
}

和另一个包含此文件的文件:

{
  "locale": "WORLD",
  "articles": [

    {
        "url": "First url"
    },
    {
        "url": "First url(1)"       
    }
]
}

所以最后我会这样:

{
  "locale": "WORLD",
  "articles": [

    {
        "url": "First url"
    },
    {
        "url": "First url(1)"       
    },
    {
        "url": "Second url"
    },
    {
        "url": "Second url"       
    }
]
}

实际上我有成千上万个这样的块(我只是简化了它们),我必须将它们分为火车(80%)和测试(20%)。谁能帮我?

1 个答案:

答案 0 :(得分:0)

我建议,您只需将反序列化 - 转换 - 序列化作为转换方案​​。

非压缩合并(将冗余的dicts /对象保留为{"url": "whatever"}作为“文章”键列表的元素:

#! /usr/bin/env python
from __future__ import print_function
import json


JSON_TEXTS = (
    ('{"locale": "WORLD", "articles": ['
     '{"url": "Second url"},{"url": "Second url"}]}'),
    ('{"locale": "WORLD", "articles": ['
     '{"url": "First url"}, {"url": "First url(1)"}]}'))


combined = {'locale': 'WORLD', 'articles': []}
for json_text in JSON_TEXTS:
    parsed = json.loads(json_text)
    if parsed['locale'] == combined['locale']:
        urls = ([v['url'] for v in parsed['articles']])
        for url in urls:
            combined['articles'].append({'url': url})

print(combined)

的产率:

{'locale': 'WORLD', 'articles': [{'url': u'Second url'}, {'url': u'Second url'}, {'url': u'First url'}, {'url': u'First url(1)'}]}

或美化/重新格式化为JSON:

{
  "locale": "WORLD",
  "articles": [
    {
      "url": "Second url"
    },
    {
      "url": "Second url"
    },
    {
      "url": "First url"
    },
    {
      "url": "First url(1)"
    }
  ]
}

压缩合并(删除多余的dicts /对象{"url": "whatever"}属于“文章”键列表:

#! /usr/bin/env python
from __future__ import print_function
import json


JSON_TEXTS = (
    ('{"locale": "WORLD", "articles": ['
     '{"url": "Second url"},{"url": "Second url"}]}'),
    ('{"locale": "WORLD", "articles": ['
     '{"url": "First url"}, {"url": "First url(1)"}]}'))


combined = {'locale': 'WORLD'}
unique_urls = set()
for json_text in JSON_TEXTS:
    parsed = json.loads(json_text)
    if parsed['locale'] == combined['locale']:
        urls = set([v['url'] for v in parsed['articles']])
        unique_urls |= urls

combined['articles'] = [{'url': u} for u in unique_urls]
print(combined)

在我的机器上产生(这里是python2):

{'locale': 'WORLD', 'articles': [{'url': u'First url'}, {'url': u'Second url'}, {'url': u'First url(1)'}]}

或美化/重新格式化为JSON:

{
  "locale": "WORLD",
  "articles": [
    {
      "url": "First url"
    },
    {
      "url": "Second url"
    },
    {
      "url": "First url(1)"
    }
  ]
}

也可以使用开箱即用的python3。您当然必须使用json.load(...)json.dump()(或自制的序列化程序,以便大小写顺序)来读取输入数据并将过滤后的/组合数据放入磁盘。

现在,它使用字符串以便于在答案中显示,在现实生活中,您必须翻阅文件并写出结果。

所以在本质上:准备最小的dict来保存结果和中间集只保留url键的唯一值,而不是遍历json文本(文件数据)中的每一个看看locale值是否匹配,提取url键的值数组文章的对象,进入本地集,执行收集集的并集(unique_urls和从手边的json文本输入命名为local set的url。

循环结合后,将uniqe中的所有url设置为文章数组值中单独对象中键的值。完成。

序列化时键的顺序取决于某些因素,因为python dict实现的性质(具有碰撞线性的哈希值,因此还有一些插入顺序序列)和python版本。

如果你想要,例如。始终首先输出分组键,您必须通过其他措施确保。一般来说,JSON文本对象(JSON的序列)的使用者不应该依赖于键在线上或文件中出现的顺序。

此外,如果你想要遍历所有文件并且想要聚合的N个不同的键(即输入上的语言环境键的值,你只需创建组合作为序列的序列或dict的dict和循环对于每个文件的外部文件选择适用的输出组合目标(dict)具有这些目标的隔离集,然后在完成相应的N个文件后输出。