用Python转换一级JSON Key

zpqajqem  于 2023-02-06  发布在  Python
关注(0)|答案(4)|浏览(130)

我有以下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'这样的"键"是UNIX时间戳,我需要在Python中转换。
以下是我目前掌握的情况:

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',这意味着它访问的级别低于我试图更改的级别。
我知道定义中的逻辑可以输出所需的字符串作为最终结果,但是访问这些字符串并将其替换为当前逻辑是行不通的。
最终输出需要类似于:

{
    "12 November, 2020":
    [
        {
            "id": "1",
            "value": "1. Choice 1",
            "checked": true
        },
...
vzgqcmou

vzgqcmou1#

您最好创建一个新的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}]}
jm81lzqq

jm81lzqq2#

您的意思是:

data = json.loads(data)

data = convert_timestamp(data)
dgjrabp2

dgjrabp23#

您在json.loads中误用了object_hook参数。
从文件上看
object_hook是一个可选函数,将使用任何对象文本解码的结果(dict)调用该函数。将使用object_hook的返回值而不是dict。此功能可用于实现自定义解码器(例如JSON-RPC类提示)。
因此,它会获取键找到的第一个对象。正如@quamrana在他的答案中提到的,你需要做:

json_data = json.loads(data)
converted_data = convert_timestamp(json_data)

此外,不覆盖数据而使用单独的变量也被认为是一种良好的做法。

1bqhqjot

1bqhqjot4#

下面是我最终解决这个问题的方法:

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())))

从本质上讲,将键拉到列表中,执行转换,然后将该列表作为新键合并回值,而不是尝试一次性完成,这可能不是理想的,但对于本用例,它将工作。
此答案以edit的形式发布,针对问题“使用Python转换一级JSON密钥-由CC BY-SA 4.0下的OP Hayden解决”。

相关问题