Является ли список понимания правильным способом объединения этих файлов JSON Python? - PullRequest
0 голосов
/ 05 ноября 2018

Как я могу использовать понимание списка Python для замены значений в одном файле JSON связанными значениями в отдельном файле JSON?

Один из них будет выглядеть следующим образом и будет иметь значение «a», которое мне нужно использовать для замены значения в другом списке, используя «b» в качестве соединителя (значения a, b и c являются уникальными идентификаторами):

{
   "records":[
      {
         "a": "7hk2k989u23lesdfsfd",
         "b":"b8",
      },
      {
         "a": "9ty562349u23lesdfsfd",
         "b":"b6",
      },
      {
         "a": "Ur233Fglesdfsfd",
         "b":"b2",
      }
   ]
}

другой будет выглядеть так, где «d» нужно заменить соответствующими значениями «a», где «b» - это ключ:

{
   "records":[
      {
         "c":00023414,
         "d":["b8","b6"]
      },
      {
         "c":0005814,
         "d":["b8","b2","b6"]
      }
   ]
}

Итак, я получаю:

{
   "records":[
      {
         "c":00023414,
         "d":["7hk2k989u23lesdfsfd","9ty562349u23lesdfsfd"]
      },
      {
         "c":0005814,
         "d":["7hk2k989u23lesdfsfd","Ur233Fglesdfsfd","9ty562349u23lesdfsfd"]
      }
   ]
}

Как правильно подходить к этому с помощью python, особенно если мне нужен код для обеспечения производительности?

1 Ответ

0 голосов
/ 05 ноября 2018

Ваши файлы не являются действительными JSON. Вы должны проверить с помощью JSON-валидатора, например JSON Lint

In [494]: import json

In [495]: with open('/Users/ado/Desktop/ab.json') as f:
     ...:     ab = json.load(f)
     ...:

In [496]: with open('/Users/ado/Desktop/cd.json') as f:
     ...:     cd = json.load(f)
     ...:

Обратите внимание, что вы можете рассматривать ab просто как набор связанных a s и b s. Это прекрасное время для использования словаря, сопоставляющего b с a с

In [497]: d_ab = {r['b']: r['a'] for r in ab['records']}

In [498]: d_ab
Out[498]:
{'b2': 'Ur233Fglesdfsfd',
 'b6': '9ty562349u23lesdfsfd',
 'b8': '7hk2k989u23lesdfsfd'}

Теперь вы можете перебирать records в cd и использовать list понимание для создания новых значений

In [499]: for r in cd['records']:
     ...:     r['d'] = [d_ab.get(d) for d in r['d']]
     ...:

In [500]: cd
Out[500]:
{'records': [{'c': 23414,
   'd': ['7hk2k989u23lesdfsfd', '9ty562349u23lesdfsfd']},
  {'c': 5814,
   'd': ['7hk2k989u23lesdfsfd', 'Ur233Fglesdfsfd', '9ty562349u23lesdfsfd']}]}

Наконец, запишите новое содержимое в файл

In [502]: with open('/Users/ado/Desktop/cd-mapped.json', 'w') as f:
     ...:     f.write(json.dumps(cd))
     ...:

Это решение предполагает, что в ab всегда есть a с и b с в каждой записи.

PS для забавы вы можете использовать map и dict.get вместо понимания

In [505]: for r in cd['records']:
     ...:     r['d'] = list(map(d_ab.get, r['d']))
     ...:

In [506]: cd
Out[506]:
{'records': [{'c': 23414,
   'd': ['7hk2k989u23lesdfsfd', '9ty562349u23lesdfsfd']},
  {'c': 5814,
   'd': ['7hk2k989u23lesdfsfd', 'Ur233Fglesdfsfd', '9ty562349u23lesdfsfd']}]}

Что касается производительности, то понимание часто выходит за рамки map s

In [509]: %timeit for r in cd['records']: r['d'] = [d_ab.get(d) for d in r['d']]
     ...:
The slowest run took 7.19 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.34 µs per loop

In [511]: %timeit for r in cd['records']: r['d'] = list(map(d_ab.get, r['d']))
The slowest run took 7.19 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.74 µs per loop
...