python如果条件匹配,如何更新json列表

时间:2013-09-17 21:46:54

标签: python json list

我对西班牙语中的代码感到抱歉,但除此之外,你应该能够理解它的结构,我使用Python 3.3.2并在这里遇到问题。

leyendoestadisticas = open("listas\Estadisticas.txt", "r")
bufferestadisticas = leyendoestadisticas.read()
leyendoestadisticas.close()
if not '"'+user.name+'"' in bufferestadisticas: #If name is not found, do this
  escribiendoestadisticas = open("listas\Estadisticas.txt", 'a')
  escribiendoestadisticas.write(json.dumps([user.name, palabrasdelafrase, letrasdelafrase,
                                            "1", user.nameColor, user.fontColor, user.fontFace, user.fontSize, message.body, room.name])+"\n")
  escribiendoestadisticas.close()
else: #If name is found...
  data = []
  with open('listas\Estadisticas.txt', 'r+') as f:
    for line in f:
      data_line = json.loads(line)
      if data_line[0] == user.name: #if name matches...
        if data_line[9] == room.name: #And room also, then update info.
          data_line[1] = int(data_line[1])+int(palabrasdelafrase)
          data_line[2] = int(data_line[2])+int(letrasdelafrase)
          data_line[3] = int(data_line[3])+1
          data_line[4] = user.nameColor
          data_line[5] = user.fontColor
          data_line[6] = user.fontFace
          data_line[7] = user.fontSize
          data_line[8] = message.body
          data_line[9] = room.name
        else: #but if name is found and room doesn't matches. #PROBLEM HERE
          escribiendoestadisticas = open("listas\Estadisticas.txt", 'a')
          escribiendoestadisticas.write(json.dumps([user.name, palabrasdelafrase, letrasdelafrase,
                                                  "1", user.nameColor, user.fontColor, user.fontFace, user.fontSize, message.body, room.name])+"\n")
          escribiendoestadisticas.close()
      data.append(data_line)
      break
    f.seek(0)
    f.writelines(["%s\n" % json.dumps(i) for i in data])
    f.truncate()

它的目的是添加user.name并更新它的信息,只要该行的属性9匹配即可。如果不匹配,则使用相同的user.name向列表添加新行,但为属性9添加新值。

如果属性9匹配则完美,但如果不匹配,它正在做的是覆盖该user.name的现有值并开始计算[1],[2]和[3]中的属性从头开始。

感谢您的帮助。

编辑:使用答案中的信息进行更新:

else: 
  data = []
  with open('listas\Estadisticas.txt', 'r+') as f:
    lines = f.readlines()
  for line in lines:
    data_line = json.loads(line)
    if data_line[0] == user.name: 
      if data_line[9] == room.name:
        data_line[1] = int(data_line[1])+int(palabrasdelafrase)
        data_line[2] = int(data_line[2])+int(letrasdelafrase)
        data_line[3] = int(data_line[3])+1
        data_line[4] = user.nameColor
        data_line[5] = user.fontColor
        data_line[6] = user.fontFace
        data_line[7] = user.fontSize
        data_line[8] = message.body
        data_line[9] = room.name
      data.append(data_line)
  f.seek(0)
  f.writelines(["%s\n" % json.dumps(i) for i in data])
  f.truncate()
  for line in lines: 
    data_line = json.loads(line)
    if data_line[0] == user.name: 
      if not data_line[9] == room.name:
        escribiendoestadisticas = open("listas\Estadisticas.txt", 'a')
        escribiendoestadisticas.write(json.dumps([user.name, palabrasdelafrase, letrasdelafrase,
                                                "1", user.nameColor, user.fontColor, user.fontFace, user.fontSize, message.body, room.name])+"\n")
        escribiendoestadisticas.close()

但现在我收到错误:ValueError:关闭文件的I / O操作。 完全迷失了。

1 个答案:

答案 0 :(得分:0)

看起来你正在修改文件,同时还要从中读取文件。首先完全加载文件,然后让上下文处理程序关闭文件:

else: #Si está, suma datos
  data = []
  with open('listas\Estadisticas.txt', 'r+') as f:
      lines = f.readlines()

  for line in lines:
    data_line = json.loads(line)
    if data_line[0] == user.name: #if name is found...
      if data_line[9] == room.name: #And room also, then update info.
        data_line[1] = int(data_line[1])+int(palabrasdelafrase)
        [etc]

正如其他人在评论中指出的那样,您可能希望在整个文件中搜索user.name,而不仅仅是逐行搜索。

另外,正如@abarnert指出的那样,只需修改循环中的data,然后在最后写出完整的信息集。


几条一般性意见:

  • data_line包含少于10个项目时,您的代码无法处理此案例。如果发生这种情况,您的程序将崩溃。

  • 使用json将整个dict保存到文件会更好。这样,当您加载dict时,您可以立即检查并访问user.name。我建议你将user.name作为字典的关键。

它可能看起来像这样(编辑:看到你想要user.name和room.name的独特组合):

with open('listas\Estadisticas.json', 'rb') as f:
    data = json.load(f)

key = (user.name, room.name)

if key in data:
    data[key]['nameColor'] = user.nameColor
    [...etc...]
else:
    # I am not sure what details are different
    data[key] = {} # New sub-dict
    data[key]['nameColor'] = user.nameColor
    [...etc...]

with open('listas\Estadisticas.json', 'wb') as f:
    json.dump(f, data)
  • 名称可以更改。这就是为什么数据库通常使用的密钥不是人名或房间名称。我建议您将事物的名称分配给抽象的其他内容,例如数字,然后在需要显示时查找名称。如果用户的名字最初输入不正确,以后他们想要纠正他们名字的拼写,那么你很难向他们解释你不能,因为这意味着他们的所有数据都会丢失......