【问题标题】:Is List Comprehension the Right Way to Merge these JSON files Python?列表理解是合并这些 JSON 文件 Python 的正确方法吗?
【发布时间】:2018-11-05 02:04:22
【问题描述】:

如何使用 python 列表推导将一个 JSON 文件中的值替换为单独 JSON 文件中的链接值?

一个看起来像这样并且有一个“a”值我需要用来替换另一个列表中的值,使用“b”作为连接符(a、b 和 c 值都是唯一的 id):

{
   "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 解决这个问题的正确方法是什么,尤其是当我需要代码具有高性能时?

【问题讨论】:

    标签: python json list-comprehension dictionary-comprehension


    【解决方案1】:

    您的文件不是有效的 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 简单地视为相关as 和bs 的集合。这是使用字典将bs 映射到as 的好时机

    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'}
    

    现在您可以遍历 cd 中的 records 并使用 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 中,每条记录中始终存在as 和bs。

    对于有趣的 PS,您可以使用 mapdict.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']}]}
    

    就性能而言,理解通常优于 maps

    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
    

    【讨论】:

    • 哇,这是一个非常有用的见解,将 a 和 b 转换为 key:value!从你的例子中可以学到很多东西。
    • 列表推导是python的一个神奇特性
    • 感谢@Conando :) 如果答案对您有帮助,请考虑支持和接受
    猜你喜欢
    • 1970-01-01
    • 2020-10-12
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多