[英]Transform first level JSON Key with Python
我有以下 JSON:
{
"1605855600000":
[
{
"id": "1",
"value": "1. Choice 1",
"checked": true
},
{
"id": "2",
"value": "2. Choice 2",
"checked": false
},
{
"id": "3",
"value": "3. Choice 3",
"checked": false
},
{
"id": "4",
"value": "4. Choice 4",
"checked": false
},
{
"id": "5",
"value": "5. Choice 5",
"checked": false
}
],
"1604732400000":
[
{
"id": "1",
"value": "1. Choice 1",
"checked": false
},
{
"id": "2",
"value": "2. Choice 2",
"checked": false
},
{
"id": "3",
"value": "3. Choice 3",
"checked": false
},
{
"id": "4",
"value": "4. Choice 4",
"checked": false
},
{
"id": "5",
"value": "5. Choice 5",
"checked": false
}
]
}
我不确定确切的术语,但像“1605855600000”和“1604732400000”这样的“键”是我需要在 Python 中转换的 UNIX 时间戳。
这是我到目前为止所拥有的:
def convert_timestamp(obj):
for key in obj.keys():
timestamp = int(key) / 1000
dt_object = datetime.fromtimestamp(timestamp)
date = dt_object.strftime("%B %d, %Y")
new_key = date
if new_key != key:
obj[new_key] = obj[key]
del obj[key]
return obj
data = json.loads(data, object_hook=convert_timestamp)
但是,我收到的错误是: ValueError: invalid literal for int() with base 10: 'id'
这意味着它正在访问低于我试图更改的级别。
我知道定义中的逻辑适用于 output 作为最终结果我需要的字符串,但无法使用当前逻辑访问和替换这些字符串。
最终的 output 需要看起来像这样:
{
"12 November, 2020":
[
{
"id": "1",
"value": "1. Choice 1",
"checked": true
},
...
制作一个新的dict
比弄乱键要好得多:
import json
from datetime import datetime
data_str = '''{
"1605855600000":
[
{ "id": "1", "value": "1. Choice 1", "checked": true },
{ "id": "2", "value": "2. Choice 2", "checked": false },
{ "id": "3", "value": "3. Choice 3", "checked": false },
{ "id": "4", "value": "4. Choice 4", "checked": false },
{ "id": "5", "value": "5. Choice 5", "checked": false }
],
"1604732400000":
[
{ "id": "1", "value": "1. Choice 1", "checked": false },
{ "id": "2", "value": "2. Choice 2", "checked": false },
{ "id": "3", "value": "3. Choice 3", "checked": false },
{ "id": "4", "value": "4. Choice 4", "checked": false },
{ "id": "5", "value": "5. Choice 5", "checked": false }
]
}'''
def convert_timestamp(key):
timestamp = int(key) / 1000
dt_object = datetime.fromtimestamp(timestamp)
return dt_object.strftime("%B %d, %Y")
def convert_keys(obj):
return {convert_timestamp(key):val for (key,val) in obj.items()}
data = json.loads(data_str)
new_data = convert_keys(data)
print(new_data)
输出:
{'November 20, 2020': [{'id': '1', 'value': '1. Choice 1', 'checked': True}, {'id': '2', 'value': '2. Choice 2', 'checked': False}, {'id': '3', 'value': '3. Choice 3', 'checked': False}, {'id': '4', 'value': '4. Choice 4', 'checked': False}, {'id': '5', 'value': '5. Choice 5', 'checked': False}], 'November 07, 2020': [{'id': '1', 'value': '1. Choice 1', 'checked': False}, {'id': '2', 'value': '2. Choice 2', 'checked': False}, {'id': '3', 'value': '3. Choice 3', 'checked': False}, {'id': '4', 'value': '4. Choice 4', 'checked': False}, {'id': '5', 'value': '5. Choice 5', 'checked': False}]}
你的意思是:
data = json.loads(data)
data = convert_timestamp(data)
您在json.loads
误用了object_hook
参数。
从文档
object_hook 是一个可选函数,将使用任何对象文字解码的结果(字典)调用。 将使用 object_hook 的返回值而不是 dict。 此功能可用于实现自定义解码器(例如 JSON-RPC 类提示)。
因此,它需要键找到的第一个对象。 正如@quamrana 在他的回答中提到的,您需要执行以下操作:
json_data = json.loads(data)
converted_data = convert_timestamp(json_data)
此外,不覆盖数据而是使用单独的变量被认为是一种很好的做法。
这是我最终解决它的方法:
json_data = json.loads(data)
dict_keys = json_data.keys()
timestamp = []
for x in dict_keys:
date_val = int(x) / 1000
dt_object = datetime.fromtimestamp(date_val)
date = dt_object.strftime("%B %d, %Y")
timestamp.append(date)
final_dict = dict(zip(timestamp, list(json_data.values())))
从本质上讲,将键拉入列表、执行转换,然后将该列表作为新键合并回值,而不是尝试一次性完成,这样会更容易。 对于有严格性能要求的人来说,这可能不是理想的,但对于这个用例,它会起作用。
此答案作为对问题Transform first level JSON Key with Python的编辑发布 - 由 OP Hayden在 CC BY-SA 4.0 下解决。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.