在python中加载json的一部分
我有一个json文件,其中包含大约1000个数据条目。比如说在python中加载json的一部分,python,Python,我有一个json文件,其中包含大约1000个数据条目。比如说 {"1":"Action","2":"Adventure",....."1000":"Mystery"} 以上只是一个例子 我通过导入json来使用json.load特性。 如何仅从json加载前10个数据项 {"1":"Action","2":"Adventure",....."10":"Thriller"} 我想没有别的办法了。 您必须加载整个内容,然后才能提取所需的密钥 我想没有别的办法了。 必须加载整个内容,然后才能提取所
{"1":"Action","2":"Adventure",....."1000":"Mystery"}
以上只是一个例子
我通过导入json来使用json.load特性。
如何仅从json加载前10个数据项
{"1":"Action","2":"Adventure",....."10":"Thriller"}
我想没有别的办法了。
您必须加载整个内容,然后才能提取所需的密钥
我想没有别的办法了。
必须加载整个内容,然后才能提取所需的键。JSON对象,如Python字典,没有顺序。您也无法控制加载了多少对象,无论如何都不能使用标准库
json
模块
加载后,您可以获取具有最低键值的十个键值对:
import heapq
import json
data = json.loads(json_string)
limited = {k: data[k] for k in heapq.nsmallest(data, 10, key=int)}
无论数据的大小如何,都将有效地挑选出10个最小的键
当然,如果按键总是连续的,并且总是从1
开始,您也可以在此处使用范围()
data = json.loads(json_string)
limited = {str(k): data[str(k)] for k in range(1, 11)}
如果要按文件定义顺序捕获对象,可以使用object\u pairs\u hook
参数来json.load()
和json.load()
:
后一种方法的演示:
>>> import json
>>> class FirstTenDict(dict):
... def __init__(self, pairs):
... super(FirstTenDict, self).__init__(pairs[:10])
...
>>> json_data = '''\
... {"foo42": "bar", "foo31": "baz", "foo10": "spam", "foo44": "ham", "foo1": "eggs",
... "foo24": "vikings", "foo21": "monty", "foo88": "python", "foo11": "eric", "foo65": "idle",
... "foo13": "will", "foo31": "be", "foo76": "ignored"}
... '''
>>> json.loads(json_data)
{'foo1': 'eggs', 'foo88': 'python', 'foo44': 'ham', 'foo10': 'spam', 'foo76': 'ignored', 'foo42': 'bar', 'foo24': 'vikings', 'foo11': 'eric', 'foo31': 'be', 'foo13': 'will', 'foo21': 'monty', 'foo65': 'idle'}
>>> json.loads(json_data, object_pairs_hook=FirstTenDict)
{'foo1': 'eggs', 'foo88': 'python', 'foo44': 'ham', 'foo10': 'spam', 'foo24': 'vikings', 'foo11': 'eric', 'foo21': 'monty', 'foo42': 'bar', 'foo31': 'baz', 'foo65': 'idle'}
>>> import pprint
>>> pprint.pprint(_)
{'foo1': 'eggs',
'foo10': 'spam',
'foo11': 'eric',
'foo21': 'monty',
'foo24': 'vikings',
'foo31': 'baz',
'foo42': 'bar',
'foo44': 'ham',
'foo65': 'idle',
'foo88': 'python'}
JSON对象,如Python字典,没有顺序。您也无法控制加载了多少对象,无论如何都不能使用标准库json
模块
加载后,您可以获取具有最低键值的十个键值对:
import heapq
import json
data = json.loads(json_string)
limited = {k: data[k] for k in heapq.nsmallest(data, 10, key=int)}
无论数据的大小如何,都将有效地挑选出10个最小的键
当然,如果按键总是连续的,并且总是从1
开始,您也可以在此处使用范围()
data = json.loads(json_string)
limited = {str(k): data[str(k)] for k in range(1, 11)}
如果要按文件定义顺序捕获对象,可以使用object\u pairs\u hook
参数来json.load()
和json.load()
:
后一种方法的演示:
>>> import json
>>> class FirstTenDict(dict):
... def __init__(self, pairs):
... super(FirstTenDict, self).__init__(pairs[:10])
...
>>> json_data = '''\
... {"foo42": "bar", "foo31": "baz", "foo10": "spam", "foo44": "ham", "foo1": "eggs",
... "foo24": "vikings", "foo21": "monty", "foo88": "python", "foo11": "eric", "foo65": "idle",
... "foo13": "will", "foo31": "be", "foo76": "ignored"}
... '''
>>> json.loads(json_data)
{'foo1': 'eggs', 'foo88': 'python', 'foo44': 'ham', 'foo10': 'spam', 'foo76': 'ignored', 'foo42': 'bar', 'foo24': 'vikings', 'foo11': 'eric', 'foo31': 'be', 'foo13': 'will', 'foo21': 'monty', 'foo65': 'idle'}
>>> json.loads(json_data, object_pairs_hook=FirstTenDict)
{'foo1': 'eggs', 'foo88': 'python', 'foo44': 'ham', 'foo10': 'spam', 'foo24': 'vikings', 'foo11': 'eric', 'foo21': 'monty', 'foo42': 'bar', 'foo31': 'baz', 'foo65': 'idle'}
>>> import pprint
>>> pprint.pprint(_)
{'foo1': 'eggs',
'foo10': 'spam',
'foo11': 'eric',
'foo21': 'monty',
'foo24': 'vikings',
'foo31': 'baz',
'foo42': 'bar',
'foo44': 'ham',
'foo65': 'idle',
'foo88': 'python'}
简言之,你不能
虽然每个条目都是一个JSON条目,但该文件作为一个整体是一个有效的JSON文件
例如:
import ijson
def iter_items(parser):
for prefix, event, value in parser:
if event == 'string':
yield prefix, value
with open('filename.json') as infile:
items = iter_items(ijson.parser(infile))
# choose one of the following
# first 10 items from the file regardless of keys
print dict(itertools.islice(items, 10))
# least 10 keys when considered as integers
print dict(heapq.nsmallest(items, 10, lambda p: int(p[0])))
“1”:“Action”
是正确的JSON格式,但不能单独加载
为了能够将其作为JSON格式导入,您需要它的完整语法{“1”:“Action”}
您需要做的是仍然加载整个文件,然后将前10行分配给一个变量。简而言之,您不能
虽然每个条目都是一个JSON条目,但该文件作为一个整体是一个有效的JSON文件
例如:
import ijson
def iter_items(parser):
for prefix, event, value in parser:
if event == 'string':
yield prefix, value
with open('filename.json') as infile:
items = iter_items(ijson.parser(infile))
# choose one of the following
# first 10 items from the file regardless of keys
print dict(itertools.islice(items, 10))
# least 10 keys when considered as integers
print dict(heapq.nsmallest(items, 10, lambda p: int(p[0])))
“1”:“Action”
是正确的JSON格式,但不能单独加载
为了能够将其作为JSON格式导入,您需要它的完整语法{“1”:“Action”}
您需要做的是仍然加载整个文件,然后将前10行分配给一个变量。您可以使用迭代解析json(也就是说,不是“一次全部解析”),并且假设您的输入真的像您的示例一样简单:
import ijson
def iter_items(parser):
for prefix, event, value in parser:
if event == 'string':
yield prefix, value
with open('filename.json') as infile:
items = iter_items(ijson.parser(infile))
# choose one of the following
# first 10 items from the file regardless of keys
print dict(itertools.islice(items, 10))
# least 10 keys when considered as integers
print dict(heapq.nsmallest(items, 10, lambda p: int(p[0])))
显然,第二种方法仍然需要读取整个文件,它不需要立即将整个文件保存在内存中。避免这种情况是对1000个小键值对的过早优化,但不管怎样。我发现这个问题非常有趣,可以使用一个我以前从未考虑过的库,因为有时候json文件非常大,而且与SAX解析器(基于事件的XML流式解析器)非常相似
顺便说一下,如果顺序很重要,那么这个JSON的生产者可能应该在JSON中放入一个数组。但作为消费者,您可能对此无能为力。您可以使用迭代解析json(也就是说,不是“一次全部解析”),并且假设您的输入真的像您的示例一样简单:
import ijson
def iter_items(parser):
for prefix, event, value in parser:
if event == 'string':
yield prefix, value
with open('filename.json') as infile:
items = iter_items(ijson.parser(infile))
# choose one of the following
# first 10 items from the file regardless of keys
print dict(itertools.islice(items, 10))
# least 10 keys when considered as integers
print dict(heapq.nsmallest(items, 10, lambda p: int(p[0])))
显然,第二种方法仍然需要读取整个文件,它不需要立即将整个文件保存在内存中。避免这种情况是对1000个小键值对的过早优化,但不管怎样。我发现这个问题非常有趣,可以使用一个我以前从未考虑过的库,因为有时候json文件非常大,而且与SAX解析器(基于事件的XML流式解析器)非常相似
顺便说一下,如果顺序很重要,那么这个JSON的生产者可能应该在JSON中放入一个数组。但作为消费者,你可能对此无能为力。你有两个选择:
如果使用Python>=3.1,则可以使用
from collections import OrderedDict
decoder = json.JSONDecoder(object_pairs_hook=OrderedDict)
data = decoder.decode(datastring)
这将解码整个文件,但保持所有键值对的顺序与文件中的顺序相同
然后,您可以使用以下内容对前n个项目进行切片
result = OrderedDict((k,v) for (k,v),i in zip(data.items(), range(n)))
这不是很有效,但您将获得前10个条目,因为它们是用JSON编写的
第二种选择,也是效率更高但难度更大的选择,是使用@steve jessop提到的迭代JSON解析器,如ijson
如果且仅当您的JSON文件始终是平面的(不包含任何子对象或列表),如您在问题中的示例,以下代码将把前10个元素放入结果中。更复杂的文件需要更复杂的解析器代码
import ijson
result = {}
for prefix, event, value in ijson.parse(file):
if event == 'map_key':
if len(result) > 10:
break
if prefix:
result[prefix] = value
您有两个选择:
如果使用Python>=3.1,则可以使用
from collections import OrderedDict
decoder = json.JSONDecoder(object_pairs_hook=OrderedDict)
data = decoder.decode(datastring)
这将解码整个文件,但保持所有键值对的顺序与文件中的顺序相同
然后,您可以使用以下内容对前n个项目进行切片
result = OrderedDict((k,v) for (k,v),i in zip(data.items(), range(n)))
这不是很有效,但您将获得前10个条目,因为它们是用JSON编写的
第二种选择,也是效率更高但难度更大的选择,是使用@steve jessop提到的迭代JSON解析器,如ijson
如果且仅当您的JSON文件始终是平面的(不包含任何子对象或列表),如您在问题中的示例,以下代码将把前10个元素放入结果中。更复杂的文件需要更复杂的解析器代码
import ijson
result = {}
for prefix, event, value in ijson.parse(file):
if event == 'map_key':
if len(result) > 10:
break
if prefix:
result[prefix] = value
JSON是一个对象repr