You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以Pythonic方式为json.loads传递两个object_pairs_hook参数?

How to Combine KeepDuplicates and OrderedDict for json.loads' object_pairs_hook

First off, your current code will throw a SyntaxError right away—Python doesn’t let you pass the same keyword argument twice (even if it didn’t error, the second object_pairs_hook would overwrite the first, which isn’t what you want). The fix here is to create a single hook that handles both requirements: preserving duplicate keys AND maintaining the original order of the JSON input.

Let’s walk through two clean, Pythonic approaches:

1. Create a Custom Class Inheriting from OrderedDict

If you already have a KeepDuplicates class, you can modify it to inherit from OrderedDict (from the collections module) so it retains order while handling duplicates. Here’s how that might look:

from collections import OrderedDict
import json

class OrderedKeepDuplicates(OrderedDict):
    def __setitem__(self, key, value):
        # Handle duplicate keys: convert existing value to a list if needed
        if key in self:
            if isinstance(self[key], list):
                self[key].append(value)
            else:
                self[key] = [self[key], value]
        else:
            # Use OrderedDict's default behavior for new keys
            super().__setitem__(key, value)

# Usage example
json_value = '{"a": 1, "b": 2, "a": 3}'
raw_data = json.loads(json_value, object_pairs_hook=OrderedKeepDuplicates)
print(raw_data)  # Output: OrderedKeepDuplicates([('a', [1, 3]), ('b', 2)])

This class inherits all the order-preserving behavior of OrderedDict and adds logic to keep duplicate keys by storing their values in a list.

2. Use a Custom Hook Function

If you prefer not to create a new class, you can write a function that processes the key-value pairs directly, builds an ordered structure, and handles duplicates:

from collections import OrderedDict
import json

def ordered_keep_duplicates(pairs):
    result = OrderedDict()
    for key, value in pairs:
        if key in result:
            # Append to list if key already exists
            if isinstance(result[key], list):
                result[key].append(value)
            else:
                result[key] = [result[key], value]
        else:
            result[key] = value
    return result

# Usage example
json_value = '{"a": 1, "b": 2, "a": 3}'
raw_data = json.loads(json_value, object_pairs_hook=ordered_keep_duplicates)
print(raw_data)  # Output: OrderedDict([('a', [1, 3]), ('b', 2)])

Note for Python 3.7+ Users

Starting with Python 3.7, regular dict objects preserve insertion order by default. If you don’t need to support older versions, you can simplify the code by replacing OrderedDict with a standard dict:

import json

def keep_duplicates(pairs):
    result = {}
    for key, value in pairs:
        if key in result:
            if isinstance(result[key], list):
                result[key].append(value)
            else:
                result[key] = [result[key], value]
        else:
            result[key] = value
    return result

# Usage
json_value = '{"a": 1, "b": 2, "a": 3}'
raw_data = json.loads(json_value, object_pairs_hook=keep_duplicates)
print(raw_data)  # Output: {'a': [1, 3], 'b': 2} (order preserved in Python 3.7+)

The core idea here is that object_pairs_hook expects a single callable (class or function) that takes the list of (key, value) pairs from the JSON parser and returns the desired dictionary-like object. By combining both behaviors into one callable, you get exactly what you need.

内容的提问来源于stack exchange,提问作者Lowpe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:43:27