Python多层嵌套的dict递归解析
1.问题
遇到多层嵌套的dict ,如何能解析为只有一维的dict ,方便后续数据处理。
一个嵌套的dict :
AutoOrderedDict([('total',
AutoOrderedDict([('total', 9), ('open', 1), ('closed', 8)])),
('streak',
AutoOrderedDict([('won',
AutoOrderedDict([('current', 0),
('longest', 2)])),
('lost',
AutoOrderedDict([('current', 2),
('longest', 2)]))])),
('pnl',
AutoOrderedDict([('gross',
AutoOrderedDict([('total', 8391.0),
('average', 1048.875)])),
('net',
AutoOrderedDict([('total',
8153.050000000002),
('average',
1019.1312500000003)]))])),
('won',
AutoOrderedDict([('total', 4),
('pnl',
AutoOrderedDict([('total',
11173.952000000001),
('average',
2793.4880000000003),
('max', 7333.14)]))])),
('lost',
AutoOrderedDict([('total', 4),
('pnl',
AutoOrderedDict([('total',
-3020.9019999999987),
('average',
-755.2254999999997),
('max',
-1576.6519999999991)]))])),
('long',
AutoOrderedDict([('total', 8),
('pnl',
AutoOrderedDict([('total',
8153.050000000002),
('average',
1019.1312500000003),
('won',
AutoOrderedDict([('total',
11173.952000000001),
('average',
2793.4880000000003),
('max',
7333.14)])),
('lost',
AutoOrderedDict([('total',
-3020.9019999999987),
('average',
-755.2254999999997),
('max',
-1576.6519999999991)]))])),
('won', 4),
('lost', 4)])),
('short',
AutoOrderedDict([('total', 0),
('pnl',
AutoOrderedDict([('total', 0.0),
('average', 0.0),
('won',
AutoOrderedDict([('total',
0.0),
('average',
0.0),
('max',
0.0)])),
('lost',
AutoOrderedDict([('total',
0.0),
('average',
0.0),
('max',
0.0)]))])),
('won', 0),
('lost', 0)])),
('len',
AutoOrderedDict([('total', 668),
('average', 83.5),
('max', 177),
('min', 12),
('won',
AutoOrderedDict([('total', 556),
('average', 139.0),
('max', 177),
('min', 94)])),
('lost',
AutoOrderedDict([('total', 112),
('average', 28.0),
('max', 45),
('min', 12)])),
('long',
AutoOrderedDict([('total', 668),
('average', 83.5),
('max', 177),
('min', 12),
('won',
AutoOrderedDict([('total',
556),
('average',
139.0),
('max',
177),
('min',
94)])),
('lost',
AutoOrderedDict([('total',
112),
('average',
28.0),
('max',
45),
('min',
12)]))])),
('short',
AutoOrderedDict([('total', 0),
('average', 0.0),
('max', 0),
('min',
9223372036854775807),
('won',
AutoOrderedDict([('total',
0),
('average',
0.0),
('max',
0),
('min',
9223372036854775807)])),
('lost',
AutoOrderedDict([('total',
0),
('average',
0.0),
('max',
0),
('min',
9223372036854775807)]))]))]))])
2.递归解析
result_dict = {}
def parse_nested_dict(nested_dict, indent=0, pre_key=''):
for key, value in nested_dict.items():
# 如果是第一级,前缀恢复空值
if indent == 0:
pre_key = ''
# 增加前缀
new_key = pre_key + key if pre_key else key
if isinstance(value, dict):
# 递归调用
parse_nested_dict(value, indent + 1, new_key + '_')
else:
# 叶子节点,赋值到dict
result_dict[new_key] = value
# 解析嵌套字典
parse_nested_dict(TradeAnalyzer)
优雅。
3.效果
{'total_total': 9,
'total_open': 1,
'total_closed': 8,
'streak_won_current': 0,
'streak_won_longest': 2,
'streak_lost_current': 2,
'streak_lost_longest': 2,
'pnl_gross_total': 8391.0,
'pnl_gross_average': 1048.875,
'pnl_net_total': 8153.050000000002,
'pnl_net_average': 1019.1312500000003,
'won_total': 4,
'won_pnl_total': 11173.952000000001,
'won_pnl_average': 2793.4880000000003,
'won_pnl_max': 7333.14,
'lost_total': 4,
'lost_pnl_total': -3020.9019999999987,
'lost_pnl_average': -755.2254999999997,
'lost_pnl_max': -1576.6519999999991,
'long_total': 8,
'long_pnl_total': 8153.050000000002,
'long_pnl_average': 1019.1312500000003,
'long_pnl_won_total': 11173.952000000001,
'long_pnl_won_average': 2793.4880000000003,
'long_pnl_won_max': 7333.14,
'long_pnl_lost_total': -3020.9019999999987,
'long_pnl_lost_average': -755.2254999999997,
'long_pnl_lost_max': -1576.6519999999991,
'long_won': 4,
'long_lost': 4,
'short_total': 0,
'short_pnl_total': 0.0,
'short_pnl_average': 0.0,
'short_pnl_won_total': 0.0,
'short_pnl_won_average': 0.0,
'short_pnl_won_max': 0.0,
'short_pnl_lost_total': 0.0,
'short_pnl_lost_average': 0.0,
'short_pnl_lost_max': 0.0,
'short_won': 0,
'short_lost': 0,
'len_total': 668,
'len_average': 83.5,
'len_max': 177,
'len_min': 12,
'len_won_total': 556,
'len_won_average': 139.0,
'len_won_max': 177,
'len_won_min': 94,
'len_lost_total': 112,
'len_lost_average': 28.0,
'len_lost_max': 45,
'len_lost_min': 12,
'len_long_total': 668,
'len_long_average': 83.5,
'len_long_max': 177,
'len_long_min': 12,
'len_long_won_total': 556,
'len_long_won_average': 139.0,
'len_long_won_max': 177,
'len_long_won_min': 94,
'len_long_lost_total': 112,
'len_long_lost_average': 28.0,
'len_long_lost_max': 45,
'len_long_lost_min': 12,
'len_short_total': 0,
'len_short_average': 0.0,
'len_short_max': 0,
'len_short_min': 9223372036854775807,
'len_short_won_total': 0,
'len_short_won_average': 0.0,
'len_short_won_max': 0,
'len_short_won_min': 9223372036854775807,
'len_short_lost_total': 0,
'len_short_lost_average': 0.0,
'len_short_lost_max': 0,
'len_short_lost_min': 9223372036854775807}
完美!