【问题标题】:How to subtract the two values from a json data in python如何从python中的json数据中减去两个值
【发布时间】:2020-07-09 14:25:13
【问题描述】:

我有以下 json 数据:

{
    "data": [
        {
            "id": "1",
            "type": "POK",
            "value": "34"
        },
        {
            "id": "1",
            "type": "TOK",
            "value": "32"
        },
        {
            "id": "1",
            "type": "POC",
            "value": "43"
        },
        {
            "id": "2",
            "type": "POK",
            "value": "45"
        },
        {
            "id": "2",
            "type": "TOK",
            "value": "67"
        },
        {
            "id": "3",
            "type": "POK",
            "value": "12"
        },
        {
            "id": "2",
            "type": "POC",
            "value": "23"
        },
        {
            "id": "3",
            "type": "TOK",
            "value": "34"
        },
        
    ]
}

在上面的数据中,我们可以看到id1, 2, 3,类型为POK TOK POC。我必须编写一个脚本来减去类型为POKTOK 的每个id 的值。例如,类型为POK 的id 1 从TOK 类型的id 1 中减去,所以34 - 32 得到答案2。 id 2 和 3 也是如此。

为此,我想到了首先在listdicts 中从上述json 中提取有用数据,然后减去每个值,如下所示:

import json


with open("data.json") as f:
    data = json.load(f)


l = []
for i in range(len(data['data'])):
    d = dict()
    if data['data'][i]['type'] == 'POK':
        d['id'] = data['data'][i]['id']
        d['value'] = data['data'][i]['value']
        d['type'] = 'POK'
        l.append(d)
    if data['data'][i]['type'] == 'TOK':
        d['id'] = data['data'][i]['id']
        d['timestamp'] = data['value'][i]['value']
        d['type'] = 'TOK'
        l.append(d)

现在在上面的代码之后,我有一个列表l,每个列表中有 6 个dict,其中包含数据

[
{'id': '1', 'value': '34', 'type': 'POK'}, 
{'id': '1', 'value': '32', 'type': 'TOK'}, 
{'id': '2', 'value': '45', 'type': 'POK'}, 
{'id': '2', 'value': '67', 'type': 'TOK'}, 
{'id': '3', 'value': '12', 'type': 'POK'}, 
{'id': '3', 'value': '34', 'type': 'TOK'}
]

在此之后,我无法理解如何减去类型为 'POK''TOK' 的每个 id 的值。谁能给我一些建议?有没有其他方法来处理这段代码?

【问题讨论】:

    标签: python json list dictionary


    【解决方案1】:

    以下是如何使用内置的all() 方法:

    dct = [{'id': '1', 'value': '34', 'type': 'POK'},
           {'id': '1', 'value': '32', 'type': 'TOK'},
           {'id': '2', 'value': '45', 'type': 'POK'},
           {'id': '2', 'value': '67', 'type': 'TOK'},
           {'id': '3', 'value': '12', 'type': 'POK'},
           {'id': '3', 'value': '34', 'type': 'TOK'}]
    
    for d1 in dct:
        for d2 in dct:
            if all([d1['id'] == d2['id'], d1['type'] == 'POK' ,d2['type'] == 'TOK']):
                dct.append({'id': d1['id'], 'value': str(int(d1['value'])-int(d2['value'])), 'type': 'subtracted'})
    
    print(dct)
    

    输出:

    [{'id': '1', 'value': '34', 'type': 'POK'},
     {'id': '1', 'value': '32', 'type': 'TOK'},
     {'id': '2', 'value': '45', 'type': 'POK'},
     {'id': '2', 'value': '67', 'type': 'TOK'},
     {'id': '3', 'value': '12', 'type': 'POK'},
     {'id': '3', 'value': '34', 'type': 'TOK'},
     {'id': '1', 'value': '2', 'type': 'subtracted'},
     {'id': '2', 'value': '-22', 'type': 'subtracted'},
     {'id': '3', 'value': '-22', 'type': 'subtracted'}]
    

    【讨论】:

    • 你能解释一下这行if all(d1['id'] == d2['id'], d1['type'] == 'POK' ,d2['type'] == 'TOK'):。这一行给出了意外的参数错误
    • @SAndrew 抱歉,all() 需要括号。解决它。如果lst 中的所有布尔值都为真,则all(lst) 返回True,否则返回False
    • @SAndrew 您遇到的错误是因为 all() 采用可迭代而不是多个参数。将参数作为元组或列表传递(根据刚刚进行的编辑),它应该可以工作
    【解决方案2】:

    我不认为使用字典是组织减法数据的最直观方式。这是一个关于如何实现所需操作并将它们存储在列表中的示例:

    list_of_dics = [
    {'id': '1', 'value': '34', 'type': 'POK'}, 
    {'id': '1', 'value': '32', 'type': 'TOK'}, 
    {'id': '2', 'value': '45', 'type': 'POK'}, 
    {'id': '2', 'value': '67', 'type': 'TOK'}, 
    {'id': '3', 'value': '12', 'type': 'POK'}, 
    {'id': '3', 'value': '34', 'type': 'TOK'}
    ]
    
    TOKS = []
    POKS = []
    for entry in list_of_dics:
      if entry['type'] == 'TOK':
      ## We found a TOK store it for substraction
          TOKS.append((entry['id'], entry['value']))
    
      if entry['type'] == 'POK':
      ## We found a TOK store it for substraction
          POKS.append((entry['id'], entry['value']))
    
    result = []
    
    #I use this simple for loop since both lists should be of the same size as according to what you've shown on the answer.
    for i in range(len(TOKS)):
      if TOKS[i][0] == POKS[i][0]:
      #We make the substractions since they have the same id
        result.append(int(POKS[i][1]) - int(TOKS[i][1]))
    
    print(result)
    

    【讨论】:

      【解决方案3】:

      看起来你的 for 循环除了再次构建相同的 json 对象外什么也没做。 相反,您可以直接遍历 json 并进行所需的计算。 工作示例:

      import json
      
      with open("data.json") as f:
          data = json.load(f)
      
      result = {}
      for d in data['data']:
          id = d['id']
          if d['type'] == 'POK':
              result[id] =  result.get(id, 0) + int(d['value'])
          if d['type'] == 'TOK':
              result[id] = result.get(id, 0) - int(d['value'])
      
      print(result)
      

      输出是

      {'1': 2, '2': -22, '3': -22}
      

      【讨论】:

      • 你能解释一下你的 for 循环中的两个 if 语句吗?
      • 如果 type 是 POK ,对于 id,从结果中获取值(默认为 0)并为其添加值。因此对于 id 1,值将变为 0 + 34 = 34。如果类型是 TOK,对于 id,从结果中获取值(默认 0)并减去当前值。因此对于 id 1 值将更改为 34 - 32 = 2。
      • 无法理解。为什么要添加。?
      • 为了实现 X - Y ,我正在做 0 + X - Y 因为默认字典是空的(我同时将值初始化为 0)。因此,如果您的 json 顺序发生变化.. 仍然结果将是相同的.. (X + Y) 或 (0 - Y + X) 或 (0 + X -Y) 都相同
      猜你喜欢
      • 2017-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-02
      • 1970-01-01
      • 2021-08-12
      • 2016-07-28
      • 1970-01-01
      相关资源
      最近更新 更多