Python | 包含元组的列表转 JSON,更好的做法?

2016-11-29 15:16:50 +08:00
 oddcc

原始数据是一个由元组构成的列表,每个元组包含年、月、 P 级、数量,要转换成 JSON ,具体示例如下:

# 原始数据
rs=[(2016,1,'p0',1),(2016,2,'p1',2),(2016,2,'p2',3),(2016,3,'p3',25),(2016,4,'p4',55)]

# 目标 JSON ,如果某月没有相应的 P 级的数据,要补 0
{'p2': [0, 3, 0, 0], 
 'p3': [0, 0, 25, 0], 
 'p0': [1, 0, 0, 0], 
 'p1': [0, 2, 0, 0], 
 'p4': [0, 0, 0, 55], 
 'categories': ['2016-1', '2016-2', '2016-3', '2016-4']}

下面是我的做法,是把数据先转换为 dict ,然后在遍历生成 JSON 的时候通过 setdefault 把缺失的数据补 0 。但是感觉很笨,不知道更好的做法是什么?

# coding=utf-8
rs=[(2016,1,'p0',1),(2016,2,'p1',2),(2016,2,'p2',3),(2016,3,'p3',25),(2016,4,'p4',55)]

# 预处理,把 rs 转换为字典
dict1 = {}

for (year, month, p_level, count) in rs:
    dict1.setdefault(year,{})
    dict1[year].setdefault(month,{})
    dict1[year][month].setdefault(p_level,{})
    dict1[year][month][p_level] = count
# dict1 >> {2016: {1: {'p0': 1}, 2: {'p2': 3, 'p1': 2}}}

# 预处理,取年份月份和 P 级的集合,这样数据有变化也可以处理
p_levels = []
months = []
years = []

for i in rs:
    if i[0] not in years:
        years.append(i[0])

    if i[1] not in months:
        months.append(i[1])

    if i[2] not in p_levels:
        p_levels.append(i[2])
months.sort()
years.sort()

result={}
result['categories']=[str(year)+'-'+str(month) for year in years for month in months]

for p_level in p_levels:
    for month in months:
        result.setdefault(p_level,[]).append(dict1[2016][month].get(p_level, 0))

print result
# {'p2': [0, 3, 0, 0], 
# 'p3': [0, 0, 25, 0], 
# 'p0': [1, 0, 0, 0], 
# 'p1': [0, 2, 0, 0], 
# 'p4': [0, 0, 0, 55], 
# 'categories': ['2016-1', '2016-2', '2016-3', '2016-4']}
2438 次点击
所在节点    Python
2 条回复
Bryan8
2016-11-29 17:48:44 +08:00
```Python
rs = [(2016, 1, 'p0', 1), (2016, 2, 'p1', 2), (2016, 2, 'p2', 3),
(2016, 3, 'p3', 25), (2016, 4, 'p4', 55)]

dic = {'categories': []}

month = max([i[1] for i in rs])


for i in rs:
dic.setdefault(i[2], [0 for j in range(month)])
dic[i[2]][i[1] - 1] = i[3]
dic['categories'].append(str(i[0]) + '-' + str(i[1]))

print(dic)
```

这样?
oddcc
2016-11-29 18:38:27 +08:00
@Bryan8 谢谢回复,确实应该把预处理做的彻底一点,先全部初始化成 0 再填数据就好了…

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/324109

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX