更有效地从.json文件中检索特定数据?

时间:2016-09-18 06:29:12

标签: python arrays json

我有以下.json文件,其中包含一些列表,例如某些元素中的值:

{
  "paciente": [
    {
      "id": 1234,
      "nombre": "Pablo",
      "sesion": [
        {
          "id": 12345,
          "juego": [
            {
              "nombre": "bonzo",
              "nivel": [
                {
                  "id": 1234,
                  "nombre": "caida libre"
                }
              ],
              "___léeme___": "El array 'iteraciones' contiene las vitorias o derrotas con el tiempo en segundos de cada iteración",
              "iteraciones": [
                {
                  "victoria": true,
                  "tiempo": 120
                },
                {
                  "victoria": false,
                  "tiempo": 232
                }
              ]
            }
          ],
          "segmento": [
            {
              "id": 12345,
              "nombre": "Hombro",
              "movimiento": [
                {
                  "id": 12,
                  "nombre": "flexion",
                  "metricas": [
                    {
                      "min": 12,
                      "max": 34,
                      "media": 23,
                      "moda": 20
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "id": 156,
      "nombre": "Bernardo",
      "sesion": [
        {
          "id": 456,
          "juego": [
            {
              "nombre": "Rita",
              "nivel": [
                {
                  "id": 1,
                  "nombre": "NAVEGANDO"
                }
              ],
              "___léeme___": "El array 'iteraciones' contiene las vitorias o derrotas con el tiempo en segundos de cada iteración",
              "iteraciones": [
                {
                  "victoria": true,
                  "tiempo": 120
                },
                {
                  "victoria": false,
                  "tiempo": 232
                }
              ]
            }
          ],
          "segmento": [
            {
              "id": 12345,
              "nombre": "Escapula",
              "movimiento": [
                {
                  "id": 12,
                  "nombre": "Protracción",
                  "metricas": [
                    {
                      "min": 12,
                      "max": 34,
                      "media": 23,
                      "moda": 20
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

从我的脚本中,我想通过它使用不同的嵌套元素来获取特定信息

import json

with open('myfile.json') as data_file:
    data = json.loads(data_file.read())


    patient_id = data["paciente"][0]["id"]

    patient_name = data["paciente"][0]["nombre"]

    id_session = data["paciente"][0]["sesion"][0]["id"]

    game_session = data["paciente"][0]["sesion"][0]["juego"][0]["nombre"]

    level_game = data["paciente"][0]["sesion"][0]["juego"][0]["nivel"][0]["nombre"]

    iterations = data["paciente"][0]["sesion"][0]["juego"][0]["iteraciones"]

    iterations_victory = data["paciente"][0]["sesion"][0]["juego"][0]["iteraciones"][0]["victoria"]

    iterations_time = data["paciente"][0]["sesion"][0]["juego"][0]["iteraciones"][0]["tiempo"]

    iterations_victory1 = data["paciente"][0]["sesion"][0]["juego"][0]["iteraciones"][1]["victoria"]

    iterations_time1 = data["paciente"][0]["sesion"][0]["juego"][0]["iteraciones"][1]["tiempo"]

    segment = data["paciente"][0]["sesion"][0]["segmento"][0]["nombre"]

    movement = data["paciente"][0]["sesion"][0]["segmento"][0]["movimiento"][0]["nombre"]

    #metrics = data["paciente"][0]["sesion"][0]["segmento"][0]["movimiento"][0]["metricas"]

    metric_min = data["paciente"][0]["sesion"][0]["segmento"][0]["movimiento"][0]["metricas"][0]["min"]

    metric_max = data["paciente"][0]["sesion"][0]["segmento"][0]["movimiento"][0]["metricas"][0]["max"]

    metric_average = data["paciente"][0]["sesion"][0]["segmento"][0]["movimiento"][0]["metricas"][0]["media"]

    metric_moda = data["paciente"][0]["sesion"][0]["segmento"][0]["movimiento"][0]["metricas"][0]["moda"]

    print(
        'Patient ID:', patient_id,'\n',
        'Patient Name:', patient_name, '\n',
        'Session:','\n',
        '  Id Session:',id_session,'\n',
        '  Game:', game_session, '\n',
        '  Level:', level_game, '\n',
        '  Iterations:', len(iterations),'\n',
        '    Victory:', iterations_victory, '\n',
        '    Time:', iterations_time, '\n',
        '    Victory:', iterations_victory1, '\n',
        '    Time:', iterations_time1, '\n',
        '  Affected Segment:', segment, '\n',
        '    Movement:', movement, '\n',
        '       Metrics:','\n',
        '          Minimum:', metric_min, '\n'
        '          Maximum:', metric_max, '\n'
        '          Average:', metric_average, '\n'
        '          Moda/Trend:', metric_moda, '\n'

        )

这是我的输出:

Patient ID: 1234
 Patient Name: Pablo
 Session:
   Id Session: 12345
   Game: bonzo
   Level: caida libre
   Iterations: 2
     Victory: True
     Time: 120
     Victory: False
     Time: 232
   Affected Segment: Hombro
     Movement: flexion
        Metrics:
           Minimum: 12
          Maximum: 34
          Average: 23
          Moda/Trend: 20

[Finished in 0.0s]

是否可以优化此代码? 如何使这段代码更具可读性或更短?

我特别喜欢在列表/数组中查询更多的一个元素(如果存在的话),如段,移动,迭代,游戏等等

欢迎任何方向。

2 个答案:

答案 0 :(得分:1)

根据您的程序正在执行的操作,如果您加快代码的速度,可能会有所不同。您应该使用profilecProfile模块来查找脚本花费时间的位置并对其进行处理。

无论如何,您可以通过使用临时变量来保存结果来删除所有冗余索引操作,从而节省一些处理时间。您可以将此简单视为删除公共前缀。如果你有一个好的代码编辑器,这相对容易。

虽然它可能不是更短或更易读的代码,但它可能会执行得更快(尽管涉及一些开销)。

以下是我所描述的内容:

import json

with open('myfile.json') as data_file:
    data = json.loads(data_file.read())

    patient0_data = data["paciente"][0]

    patient_id = patient0_data["id"]
    patient_name = patient0_data["nombre"]

    patient0_data_sesion0 = patient0_data["sesion"][0]

    id_session = patient0_data_sesion0["id"]

    patient0_data_sesion0_juego0 = patient0_data_sesion0["juego"][0]

    game_session = patient0_data_sesion0_juego0["nombre"]
    level_game = patient0_data_sesion0_juego0["nivel"][0]["nombre"]
    iterations = patient0_data_sesion0_juego0["iteraciones"]

    patient0_data_sesion0_juego0_iteraciones = patient0_data_sesion0_juego0["iteraciones"]

    iterations_victory = patient0_data_sesion0_juego0_iteraciones[0]["victoria"]
    iterations_time = patient0_data_sesion0_juego0_iteraciones[0]["tiempo"]
    iterations_victory1 = patient0_data_sesion0_juego0_iteraciones[1]["victoria"]
    iterations_time1 = patient0_data_sesion0_juego0_iteraciones[1]["tiempo"]

    patient0_data_sesion0_segmento0 = patient0_data_sesion0["segmento"][0]

    segment = patient0_data_sesion0_segmento0["nombre"]

    patient0_data_sesion0_segmento0_movimiento0 = (
                                    patient0_data_sesion0_segmento0["movimiento"][0])

    movement = patient0_data_sesion0_segmento0_movimiento0["nombre"]
    #metrics = patient0_data_sesion0_segmento0_movimiento0["metricas"]

    patient0_data_sesion0_segmento0_movimiento0_metricas0 = (
                        patient0_data_sesion0_segmento0["movimiento"][0]["metricas"][0])

    metric_min = patient0_data_sesion0_segmento0_movimiento0_metricas0["min"]
    metric_max = patient0_data_sesion0_segmento0_movimiento0_metricas0["max"]
    metric_average = patient0_data_sesion0_segmento0_movimiento0_metricas0["media"]
    metric_moda = patient0_data_sesion0_segmento0_movimiento0_metricas0["moda"]

    print(
        'Patient ID:', patient_id,'\n',
        'Patient Name:', patient_name, '\n',
        'Session:','\n',
        '  Id Session:',id_session,'\n',
        '  Game:', game_session, '\n',
        '  Level:', level_game, '\n',
        '  Iterations:', len(iterations),'\n',
        '    Victory:', iterations_victory, '\n',
        '    Time:', iterations_time, '\n',
        '    Victory:', iterations_victory1, '\n',
        '    Time:', iterations_time1, '\n',
        '  Affected Segment:', segment, '\n',
        '    Movement:', movement, '\n',
        '       Metrics:','\n',
        '          Minimum:', metric_min, '\n'
        '          Maximum:', metric_max, '\n'
        '          Average:', metric_average, '\n'
        '          Moda/Trend:', metric_moda, '\n'

        )

答案 1 :(得分:1)

请注意,您省略了数据中的第二个患者记录(Bernardo),并且您认为总有两次迭代。这可能并非总是如此。

当你寻找速度时,你的代码接近你能得到的最好的代码,但由于上述原因,你可能会做一些很好的添加一些测试和循环以确保你覆盖所有数据,而不是更多。< / p>

这是一个可用于根据您传递的模板打印格式数据的功能。该模板列出了要用于要为其打印值的键的所有标签。为了避免歧义,模板需要感兴趣元素的键和父键。

由于该功能需要按顺序访问密钥,因此使用OrderedDict代替dict

import json
from collections import OrderedDict

data = json.loads(data, object_pairs_hook=OrderedDict)

def pretty(template, item, parentName='', name='', indent=0):
    label = template.get(parentName + '/' + name)
    if label:
        label = '  ' * indent + label + ': '
        if isinstance(item, list):
            label += str(len(item))
        elif not isinstance(item, OrderedDict):
            label += str(item)
        print(label)
    if isinstance(item, list):
        for value in item:
            pretty(template, value, parentName + '[]', name, indent)
    elif isinstance(item, OrderedDict):
        for key, value in item.items():
            pretty(template, value, name, key, indent+1)


template = {
    "paciente/id": "Patient ID",
    "paciente/nombre": "Patient Name",
    "paciente/sesion": "Sessions",
    "sesion/id": "Id Session",
    "juego/nombre": "Game",
    "nivel/nombre": "Level",
    "juego/iteraciones": "Iterations",
    "iteraciones/victoria": "Victory",
    "iteraciones/tiempo": "Time",
    "segmento/nombre": "Affected Segment",
    "movimiento/nombre": "Movement",
    "movimiento/metricas": "Metrics",
    "metricas/min": "Minimum",
    "metricas/max": "Maximum",
    "metricas/media": "Average",
    "metricas/moda": "Moda/Trend"
}

pretty(template, data)

输出结果为:

    Patient ID: 1234
    Patient Name: Pablo
    Sessions: 1
      Id Session: 12345
        Game: bonzo
          Level: caida libre
        Iterations: 2
          Victory: True
          Time: 120
          Victory: False
          Time: 232
        Affected Segment: Hombro
          Movement: flexion
          Metrics: 1
            Minimum: 12
            Maximum: 34
            Average: 23
            Moda/Trend: 20
    Patient ID: 156
    Patient Name: Bernardo
    Sessions: 1
      Id Session: 456
        Game: Rita
          Level: NAVEGANDO
        Iterations: 2
          Victory: True
          Time: 120
          Victory: False
          Time: 232
        Affected Segment: Escapula
          Movement: Protracción
          Metrics: 1
            Minimum: 12
            Maximum: 34
            Average: 23
            Moda/Trend: 20