繁体   English   中英

用 Python 转换一级 JSON Key

[英]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.

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