如何使用Python删除JSON对象?

16

我正在使用Python来删除和更新由用户提供的数据生成的JSON文件,以便只有少量项存储在数据库中。我想从JSON文件中删除特定对象。

我的JSON文件是:

[
  {
      "ename": "mark",
      "url": "Lennon.com"
  },
  {
      "ename": "egg",
      "url": "Lennon.com"
  }
]

我想删除具有enamemark的JSON对象。

由于我是Python的新手,我尝试通过将对象转换为字典来删除它,但没有成功。还有其他方法可以实现吗? 我尝试了以下方法:

index=0
while index < len(data):
    next=index+1
    if(data[index]['ename']==data[next]['ename']):
        print "match found at"
        print "line %d and %d" %(next,next+1)
        del data[next]
    index +=1

2
你能展示一下你尝试过的代码吗? - RyPeck
当您运行此程序时,是否因为文件未更改而出现问题? - RyPeck
1
使用 open('try.json') 打开文件,然后使用 json.load() 方法将数据加载到变量 data 中。 - arglee
5个回答

28

以下是一个完整的示例,它加载JSON文件,删除目标对象,然后将更新后的JSON对象输出到文件中。

#!/usr/bin/python                                                               

# Load the JSON module and use it to load your JSON file.                       
# I'm assuming that the JSON file contains a list of objects.                   
import json
obj  = json.load(open("file.json"))

# Iterate through the objects in the JSON and pop (remove)                      
# the obj once we find it.                                                      
for i in xrange(len(obj)):
    if obj[i]["ename"] == "mark":
        obj.pop(i)
        break

# Output the updated file with pretty JSON                                      
open("updated-file.json", "w").write(
    json.dumps(obj, sort_keys=True, indent=4, separators=(',', ': '))
)
主要意思是,我们通过在加载的列表中迭代对象来查找对象,一旦找到就将对象从列表中弹出。如果您需要删除列表中的多个对象,则应存储要删除的对象的索引,然后在达到 for 循环结尾后一次性删除它们(您不希望在迭代时修改列表)。

它不起作用。当我运行它时,它没有从列表中弹出标记。 - arglee
1
嗯,我用你提供的输入运行了那个脚本,标记已被移除。该脚本输出到一个名为 'updated-file.json' 的新文件中,因此它不会更新原始文件。也许这就是问题所在? - mdml
我实际上粘贴了你的相同代码,但它仍然无法工作。它生成的文件与之前相同。 - arglee
顺便提一下,要记住你不能使用 for x in obj 迭代 obj,因为这样会修改 obj 本身。 - alexandernst
1
仅供参考:在Python 3中,xrange已经不存在了。 - yuv

11
正确的处理json的方式是反序列化它,修改创建的对象,然后如果需要,将它们重新序列化为json格式。 要做到这一点,可以使用json模块。简而言之,使用<反序列化的对象> = json.loads(<一些json字符串>)来读取json,使用<json输出> = json.dumps(<你的对象>)来创建json字符串。 在你的示例中,应该这样做:
import json
o = json.loads("""[
    {
        "ename": "mark",
        "url": "Lennon.com"
    },
    {
        "ename": "egg",
        "url": "Lennon.com"
    }
]""")
# kick out the unwanted item from the list
o = filter(lambda x: x['ename']!="mark", o)
output_string = json.dumps(o)

这个解决方案更简洁。 - Shark Deng

2

你的JSON文件包含了一个对象列表,这些对象在Python中是字典。只需用不包含该对象的新列表替换原来的列表:

import json

with open('testdata.json', 'rb') as fp:
    jsondata = json.load(fp)

jsondata = [obj for obj in jsondata if obj['ename'] != 'mark']

print(json.dumps(jsondata, indent=4))

0
你需要使用 json 模块。我假设你在使用 Python2。尝试这样做:
import json
json_data = json.loads('<json_string>')

for i in xrange(len(json_data)):
  if(json_data[i]["id"] == "mark"):
    del json_data[i]
    break

3
如果字典在一个不同的位置,会怎么样? - Martijn Pieters
@MartijnPieters 说得好。我已经更新了我的答案,改为进行线性搜索。 - Nikhil
@user2511142 你必须解码JSON。当你尝试解码JSON文本时,你遇到了什么错误? - Nikhil
如果我使用它,它会显示TypeError:文件不支持项目删除。 - arglee
@Nikhil 我更新了我的问题,说明了我尝试过的内容,如果按照你的方式进行操作,仍然会显示以下错误信息:Traceback (most recent call last): File "try2json.py", line 13, in <module> del json_data[0] TypeError: 'file' object does not support item deletion。 - arglee

0

@lvo 谢谢,但是list.remove(0)将会从列表中删除第一个项目。我想要删除整个对象。 - arglee
1
@user2511142 看起来你正在处理一个文件,而不是一个 JSON 解码后的对象。先调用 json.load() 方法。我还在这里添加了一个移除示例:http://ideone.com/zQphUC - Ivo
@lvo 是的,我正在使用文件进行工作,但是我在cmd上使用整个内容,然后显示为已删除数据,因为当我使用命令print data [0]时,它会打印其旁边的项,但是json文件仍未更新。 - arglee
你需要使用json.dump将数据保存回去。它不会自动“重新保存”数据。 - Ivo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接