简体   繁体   English

Python:如何从元组创建嵌套字典?

[英]Python: How to create nested Dictionary from tuples?

I think this problem is similar to the previous questions in this forum.我认为这个问题与本论坛之前的问题类似。 However, I still have a problem with how to create a nested dictionary from a list of tuples.但是,我仍然对如何从元组列表创建嵌套字典有疑问。

Suppose I have the following tuple:假设我有以下元组:

my_list = [
 ('actor', 'actor_id', 'integer', 'NO'),
 ('actor', 'first_name', 'character varying', 'NO'),
 ('actor_info', 'actor_id', 'integer', 'YES'),
 ('actor_info', 'first_name', 'character varying', 'YES')]

# convert into DataFrame
col = ['table', 'col_name', 'dtype', 'isnull']
df = pd.DataFrame(mylist, columns=col)

print(df)

        table     col_name                        dtype   isnull
0       actor     actor_id                      integer     NO
1       actor   first_name            character varying     NO
2  actor_info     actor_id                      integer    YES
3  actor_info   first_name            character varying    YES

Current result:当前结果:

{
 'actor': {
    'actor_id': {'dtype': 'integer', 'isnull': 'NO'},
    'first_name': {'dtype': 'character varying', 'isnull': 'NO'}
    },
 'actor_info': {
    'actor_id': {'dtype': 'integer', 'isnull': 'YES'},
    'first_name': {'dtype': 'character varying', 'isnull': 'YES'}
    }
}

The expected result (it should be grouped by table_name):预期结果(应按 table_name 分组):

{
 'actor': 
    [
        {'column': 'actor_id', 'dtype': 'integer', 'isnull': 'NO'},
        {'column': 'first_name', 'dtype': 'character varying', 'isnull': 'NO'}
    ],
 'actor_info': 
    [
        {'column': 'actor_id', 'dtype': 'integer', 'isnull': 'YES'},
        {'column': 'first_name', 'dtype': 'character varying', 'isnull': 'YES'}
    ]
}

I've tried to make a nested dictionary by converting my_list to DataFrame .我试图通过将 my_list 转换为DataFrame来制作嵌套字典。 However, I cannot get the desired output result.但是,我无法获得所需的输出结果。 This is my current code :这是我当前的代码

# convert to nested dictionary
ff = df.iloc.groupby(['table'])[['col_name','dtype','isnull']].apply(lambda x: x.set_index('col_name').to_dict(orient='index')).to_dict()

# convert to JSON
print(json.dumps(ff, indent=1))

Could you help me to solve this kind of problem?你能帮我解决这种问题吗?

I'm also curious about how to solve this problem without converting to DataFrame (eg, list comprehension, nested looping) .我也很好奇如何在转换为 DataFrame 的情况下解决这个问题(例如,列表理解、嵌套循环) Any help to clear this problem up would be much appreciated.任何帮助解决这个问题将不胜感激。 Thanks谢谢

As per my comment, I'm assuming you'll want a list of columns metadata per table name, rather dict of dicts.根据我的评论,我假设您需要每个表名的列元数据列表,而不是 dict 的 dict。

If so, this is one straightforward approach.如果是这样,这是一种直接的方法。

from collections import defaultdict

d = defaultdict(list)

for tablename, col, dtype, isnull in my_list:
    d[tablename].append({ 'column': col, 'dtype': dtype, 'isnull': isnull })

Output (in ipython):输出(在 ipython 中):

In [19]: d
Out[19]:
defaultdict(list,
            {'actor': [{'column': 'actor_id',
               'dtype': 'integer',
               'isnull': 'NO'},
              {'column': 'first_name',
               'dtype': 'character varying',
               'isnull': 'NO'}],
             'actor_info': [{'column': 'actor_id',
               'dtype': 'integer',
               'isnull': 'YES'},
              {'column': 'first_name',
               'dtype': 'character varying',
               'isnull': 'YES'}]})

In [20]: d['actor']
Out[20]:
[{'column': 'actor_id', 'dtype': 'integer', 'isnull': 'NO'},
 {'column': 'first_name', 'dtype': 'character varying', 'isnull': 'NO'}]

In [21]: d['actor_info']
Out[21]:
[{'column': 'actor_id', 'dtype': 'integer', 'isnull': 'YES'},
 {'column': 'first_name', 'dtype': 'character varying', 'isnull': 'YES'}]

Quite easy with a dictionary comprehension:字典理解很容易:

from itertools import groupby

{k: {a: dict(zip(('column', 'dtype', 'isnull'), b])) for _,a,*b in g}
 for k,g in groupby(my_list, lambda t: t[0])}

NB.注意。 groupby assumes that the initial array is sorted by the grouping key, if not you need to sort it first groupby 假设初始数组按分组键排序,如果不是,则需要先对其进行排序

Output:输出:

{'actor': {'actor_id': {'column': 'integer', 'dtype': 'NO'},
  'first_name': {'column': 'character varying', 'dtype': 'NO'}},
 'actor_info': {'actor_id': {'column': 'integer', 'dtype': 'YES'},
  'first_name': {'column': 'character varying', 'dtype': 'YES'}}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM