Python如何从json获取第一个密钥

时间:2018-04-17 15:26:36

标签: python json

我使用Json进行NLP / ML,这意味着我的json文件是HUUUGE。

使用MyPy(不要混淆这是python。)

import json
from pprint import pprint
from typing import List

from Models.NewsDataModel import NewsDataModel, CreateNewNewsModelFromJson

jsonDataPath = "../DataSource/evileye-quorraengine-News-export.json"
rootJson = json.load(open(jsonDataPath))


def GetNewsData(max:int=0, hasMaxValue:bool=False)->List[NewsDataModel]:
    newsDataList = []

    jsonKeys = rootJson.keys()

    for newsDataKey in jsonKeys:

        newNewsData = CreateNewNewsModelFromJson(rootJson[newsDataKey])
        newsDataList.append(newNewsData)
        if hasMaxValue and len(newsDataList) >= max:
            break

    return newsDataList

但是。因为我有120000个按键,所以只获取按键需要5秒以上。 我怎么能限制检索钥匙?

2 个答案:

答案 0 :(得分:0)

好吧,你可以使用python普通词典,如question中所述:

  

"第一个"没有这样的事情。密钥,因为dict不记得先插入了哪些密钥。

但是,同样的问题显示了使用itertools recipes解决此问题的方法,特别是islice(iterable, start, stop[, step])方法,并且如docs中所述:

  

如果start为非零,则跳过iterable中的元素,直到达到start。之后,连续返回元素,除非将step设置为高于导致跳过项目的步骤。如果stop为None,则迭代继续,直到迭代器耗尽,如果有的话; 否则,它会停在指定位置

不幸的是,我没有足够大的字典来试用它,但是,如果它仍然需要比你想要的更长的时间,你可以尝试使用OrderedDict,如图所示here虽然我认为它的表现不如itertools.islice

答案 1 :(得分:0)

似乎json.load必须先处理整个字符串。放入字典形式需要的时间可以忽略不计。您可以使用object_pairs_hook kwarg控制输出。这可以帮助您维护订单,但不会加快速度。 (可能会有微不足道的时差,但瓶颈是解析字符串)这是120,000键字典上的时间。

In[141]: test = {x:x for x in range(120000)}
In[142]: tst_str = json.dumps(test)
In[143]: %timeit json.loads(tst_str, object_pairs_hook=lambda x: x)[:10]
10 loops, best of 3: 55.7 ms per loop
In[144]: %timeit tester=json.loads(tst_str, object_pairs_hook=lambda x: iter(x));[next(tester) for _ in range(10)]
10 loops, best of 3: 54.4 ms per loop
In[145]: %timeit json.loads(tst_str)
10 loops, best of 3: 57.5 ms per loop
In[146]: json.loads(tst_str, object_pairs_hook=lambda x: x)[:10]
Out[146]: 
[('0', 0),
 ('1', 1),
 ('2', 2),
 ('3', 3),
 ('4', 4),
 ('5', 5),
 ('6', 6),
 ('7', 7),
 ('8', 8),
 ('9', 9)]
In[147]: tester=json.loads(tst_str, object_pairs_hook=lambda x: iter(x))
In[148]: tester
Out[148]: <list_iterator at 0x86caef0>
In[149]: [next(tester) for _ in range(10)]
Out[149]: 
[('0', 0),
 ('1', 1),
 ('2', 2),
 ('3', 3),
 ('4', 4),
 ('5', 5),
 ('6', 6),
 ('7', 7),
 ('8', 8),
 ('9', 9)]