python - 在python中过滤json对象的json数组的有效方法
问题描述
我有一个这样的 json 样本:
{"ratings": [{
"TERM": "movie1",
"Rating": "3.5",
"source": "15786"
},
{
"TERM": "movie2",
"Rating": "3.5",
"source": "15786"
},
{
"TERM": "Movie1",
"Rating": "3.0",
"source": "15781"
}
]}
现在我想从中创建一个新的 json 文件,如果 TERM 已经存在一次,过滤的逻辑是忽略 json 对象。所以,对于这个样本,输出将是
{"ratings": [{
"TERM": "movie1",
"Rating": "3.5",
"source": "15786"
},
{
"TERM": "movie2",
"Rating": "3.5",
"source": "15786"
}
]}
由于 movie1 已经存在于索引 0 中,我们希望忽略索引 2。
我想出了以下逻辑,它适用于小样本。我有一个 json 数组大小为 10 百万的示例,下面的代码需要 2 天以上才能完成。我想知道是否有更有效的方法来做到这一点:
import json
import io
input1 = "movies.json"
res=[]
resTerms = []
with io.open(input1, encoding="utf8") as json_data:
d = json.load(json_data)
print(len(d['ratings']))
for x in d['ratings']:
if x['TERM'].lower() not in resTerms:
res.append(x)
resTerms.append(x['TERM'].lower())
final ={}
final["ratings"] = res
output = "myFileSelected.json"
with io.open(output, 'w') as outfile:
json.dump(final, outfile)
解决方案
这里的问题是当您检查该术语是否已经存在时(即当您检查时if x['TERM'].lower() not in resTerms:
)。这是因为resTerms
是 alist
并且查找复杂度是 O(n) 因此整个算法变为 O(n^2)
解决这个问题的方法是使用 aset
而不是 alist
如果 O(1) 则具有查找复杂性。然后你的循环看起来像这样(你也不需要保持 json 文件打开)
import json
import io
input1 = "movies.json"
res=[]
resTerms = set()
with io.open(input1, encoding="utf8") as json_data:
d = json.load(json_data)
print(len(d['ratings']))
for x in d['ratings']:
if x['TERM'].lower() not in resTerms:
res.append(x)
resTerms.add(x['TERM'].lower())
可以在此处找到 Python 数据结构和时间复杂性的便捷指南: https ://wiki.python.org/moin/TimeComplexity
推荐阅读
- perforce - 如何在 perforce p4v 中删除不在任何更改列表中的选定工作区中的所有克隆的本地文件和文件夹?
- css - 如何使滚动出现在左侧而不是右侧?(CSS)
- javascript - 设置 div 在某个点开始滚动
- javascript - 如何删除从各个元素动态创建的事件侦听器?
- laravel - 在 laravel 关系中执行查询
- python - 私有名称修改( __A 与 __A__ )
- nginx - Docker-Compose 无法从网络访问我的 http
- php - 如果mysql中没有记录,php显示默认图像
- c++ - 向量和其他容器如何在磁盘上工作?
- typescript - 使用 express-validator 时未键入 Express 请求处理程序