【问题标题】:Python 3: ordering keys in specific order in objects within an arrayPython 3:在数组中的对象中按特定顺序排序键
【发布时间】:2022-01-28 03:45:10
【问题描述】:

我目前有一些代码可以遍历 JSON 文件,获取每个对象并按字母顺序对键值对进行排序。某些键被插入到订单的前面,特别是名称和描述。

def walk_json(data, first=False):
    if isinstance(data, (dict)):
        if not first:
            data = OrderedDict(sorted(data.items()))
        for key, value in data.items():
            data[key] = walk_json(value)

    if isinstance(data, (list)):
        for index, item in enumerate(data):
            data[index] = walk_json(item)
    return data


def validate_json(filename):
    fp = None
    data = None

    try:
        fp = open(filename)
    except OSError:
        print(f"\nERROR {filename}\n")
        return

    try:
        data = json.load(fp, object_pairs_hook=OrderedDict)
    except ValueError:
        print(f"\nINVALID {filename}\n")
        badJSON.append(filename)
        return
    finally:
        fp.close()

    if data is None:
        print(f"EMPTY {filename}")
        return

    ordered = OrderedDict()
    if "display_name" in data:
        ordered["display_name"] = data["display_name"]
    if "description" in data:
        ordered["description"] = data["description"]

    ordered.update(sorted(data.items()))
    data = walk_json(ordered, True)

我有另一个文件,它是一个带有单个键的对象,build_list,它是一个包含多个对象的数组。我无法弄清楚如何执行与上述相同的操作,但对于data["build_list"] 中的每个对象。键在每个对象中按字母顺序排序,但我尝试将键 "name" 固定到每个对象的开头没有成功。

代码不是我的,所以我不会假装我完全理解它。我只是想稍微调整一下。

【问题讨论】:

  • 附带说明,要求字典键的严格排序是一种糟糕的编程习惯。 JSON 不在乎,也没有理由让您的代码在乎。
  • 这只是关于保持文件之间的相同顺序,因为这是人类将处理的所有内容。如果每个文件都有相同的密钥集,但它们都位于不同的位置,那么人们处理它们就会变得更加困难。例如,在对象中首先使用名称键会使文件对人们来说更具可读性。
  • 我只是在这里固执己见,但有人可能会争辩说,无论如何,人类不应该经常使用 JSON 数据。应该有一个友好的用户界面,减少出错的可能性。

标签: arrays python-3.x ordereddict


【解决方案1】:
def reorder_keys(obj):
    if isinstance(obj, dict):
        new_obj = OrderedDict()
        for key in key_order:
            if key in obj:
                new_obj[key] = reorder_keys(obj[key])

        for key, value in obj.items():
            new_obj[key] = reorder_keys(value)

        return new_obj

    if isinstance(obj, list):
        return list(map(reorder_keys, obj))

    return obj


# Format all the AI files and reorder the object keys
for file in Path("server/pa/ai").glob("**/*.json"):
    data, warnings = pajson.loadf(file)
    list(map(print, warnings))

    data = reorder_keys(data)

    with open(file, "w") as f:
        f.write(pajson.dumps(data, indent=2))
        f.write("\n")

【讨论】:

    猜你喜欢
    • 2010-09-26
    • 1970-01-01
    • 2021-09-10
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    相关资源
    最近更新 更多