Retrieving specific data from a .json file more efficiently?
<p>I have the following <code>.json</code> file, which have some lists like values in some elements:</p>

<pre><code>{
  "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
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
</code></pre>

<p>From my script, I want to go through it's different nested elements for get specific information</p>

<pre><code>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'

        )
</code></pre>

<p>This is my output:</p>

<pre class="lang-none prettyprint-override"><code>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]
</code></pre>

<p>Is it possible to optimize this code?
How to can I make this code more readable or short?</p>

<p>I would like especially when I will have query for more of one element (just in case of that exist) in the lists/arrays like as segment, movement, iterations, games, etc</p>

<p>Any orientation is welcome.</p>

<p>Note that you are omitting the second patient record in your data (Bernardo), and that you assume there are always exactly two iterations. This might not always be true.</p>

<p>When you look for speed, your code is close to the best you can get, but for the above reasons, you would probably do good to add some tests and loops to make sure you cover all data, and not more.</p>

<p>Here is a function you could use to print the data in your format, based on a template you pass it. The template lists all labels you want to use for the keys you want to print the values for. In order to avoid ambiguity, the template needs both the key and the parent key of the elements of interest.</p>

<p>As the function needs to visit the keys in order, <code>OrderedDict</code> is used instead of <code>dict</code>:</p>

<pre><code>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)
</code></pre>

<p>The output is:</p>

<pre class="lang-none prettyprint-override"><code>    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
</code></pre>

python arrays json