列出理解并扁平的深度数据结构



我有一个看起来如下的数据结构(这是非常简化的,我的实际数据在每个日期都有大量的日期数据(:

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来构建列表,而不是附加。想法?

可能的列表理解解决方案可能如下,在其中我们解开 job字典,然后添加 id and date键值对,同时在两个上迭代以进行loops

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

在传统的循环中看起来像

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

可以轻松地通过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,但是您需要将模块作为from functools import reduce导入。有关详细信息,请参阅下面的链接。

  • python2

  • python3

最新更新