【问题标题】:List comprehension and flattening deep data structure列表理解和扁平化深度数据结构
【发布时间】:2019-11-11 04:16:46
【问题描述】:

假设我有一个如下所示的数据结构(这已大大简化,我的实际数据在每个日期都有大量特定日期的数据):

data = {
    '2019-01-01': {
        'job-1-id': {'name': 'Job 1', 'address': '123 main st.'},
        'job-2-id': {'name': 'Job 2', 'address': '824 1st Ave.'},
    },
    '2019-01-02': {
        'job-1-id': {'name': 'Job 1', 'address': '123 main st.'},
        'job-3-id': {'name': 'Job 3', 'address': '485 Pleasant Rd.'}
    }
}

我想做的是将其展平,将datejob id 推送到对象数组。例如:

data_flat = [
    {'id': 'job-1-id', 'date': '2019-01-01', 'name': 'Job 1', 'address': '123 main st.'},
    {'id': 'job-2-id', 'date': '2019-01-01', 'name': 'Job 2', 'address': '824 1st Ave.'},
    {'id': 'job-1-id', 'date': '2019-01-02', 'name': 'Job 1', 'address': '123 main st.'},
    {'id': 'job-3-id', 'date': '2019-01-02', 'name': 'Job 3', 'address': '485 Pleasant Rd.'},
]

显然我可以查看并构建一个新数组:

data_flat = []
for date, jobs in data.items():
    for job_id, job in jobs.items():
        data_flat.append({'id': job_id, 'date': date, etc...})

但是有没有一种更 Pythonic/更有效的方法来使用带有嵌套数据的列表推导来做到这一点?我能想到的几乎都是对内部循环使用列表理解,然后使用extend 来构建列表而不是附加。想法?

【问题讨论】:

    标签: python list-comprehension flatten


    【解决方案1】:

    可以通过reduce轻松制作平面列表。

    所有你需要使用 initializer - reduce 函数中的第三个参数。

    reduce(
     lambda _list, date: _list.extend(
       {'date': date, 'id':_id, **detail} for _id, detail in data[date].items()) or _list, 
     data, 
     [])
    

    以上代码适用于 python2 和 python3,但您需要将 reduce 模块导入为 from functools import reduce。详情请参考以下链接。

    【讨论】:

      【解决方案2】:

      一个可能的列表理解解决方案可能如下,我们解包job字典并添加iddate键值对,同时迭代两个for循环

      [{**job, 'id': job_id, 'date': date} for date, jobs in data.items() for job_id, job in jobs.items()]
      

      在传统的for循环中,看起来像

      for date, jobs in data.items():
          for job_id, job in jobs.items():
              data_flat.append({**job, 'id': job_id, 'date': date})
      

      【讨论】:

        猜你喜欢
        • 2014-08-26
        • 2017-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-15
        • 2020-03-14
        • 2017-01-07
        相关资源
        最近更新 更多