首页 > 解决方案 > Python json.loads 多个回调参数

问题描述

我有一些从数据库中解析出来的 json,我需要做两件事。

  1. 确保使用内置功能且无法修改的 (OrderedDict) 维护订单
  2. 检查并重命名作为自定义函数的重复键(rename_duplicate)
def rename_duplicate(pairs):
        d = {}
        k_counter = Counter(defaultdict(int))
        for k, v in pairs:
            d[k+str(k_counter[k])] = v
            k_counter[k] += 1
  return d

使用 json.loads 时如何同时使用两者?

json.loads(raw_text_data, object_pairs_hook=OrderedDict,rename_duplicate)

错误

d = json.loads(row['Commands'], object_pairs_hook=OrderedDict,rename_duplicate)
SyntaxError: non-keyword arg after keyword arg

标签: python

解决方案


我同意 amrx 这object_pairs_hook=OrderedDict,rename_duplicate不是得到你想要的东西的正确语法。看起来你正试图告诉函数object_pairs_hook应该返回一个 OrderedDict 并且它应该调用rename_duplicate. 但是你不能像这样给一个参数提供两个值*。我认为没有必要在此处指定 OrderedDict,只要这是您从rename_duplicates.

import json
from collections import OrderedDict, Counter

def rename_duplicates(pairs):
    d = OrderedDict()
    c = Counter()
    for k,v in pairs:
        new_k = k + str(c[k])
        d[new_k] = v
        c[k] += 1
    return d

s = '{"foo": "bar", "foo": "qux", "troz": "zort", "foo": "coconuts"}'
print(json.loads(s, object_pairs_hook=rename_duplicates))

结果:

OrderedDict([('foo0', 'bar'), ('foo1', 'qux'), ('troz0', 'zort'), ('foo2', 'coconuts')])

(*好吧,从技术上讲,您可以将一个包含两个值的元组传递给它,但它仍然会崩溃,因为这个特定的参数需要一个可调用的,而元组是不可调用的)


编辑:从您的问题描述中我不清楚唯一键是否也应该重命名,以及第一次遇到非唯一键是否应该重命名。如果这两个问题的答案都是“否”,那么只需对代码稍作改动即可实现。

import json
from collections import OrderedDict, Counter

def rename_duplicates(pairs):
    d = OrderedDict()
    c = Counter()
    for k,v in pairs:
        if k not in c:
            new_k = k
        else:
            new_k = k + str(c[k])
        d[new_k] = v
        c[k] += 1
    return d

s = '{"foo": "bar", "foo": "qux", "troz": "zort", "foo": "coconuts"}'
print(json.loads(s, object_pairs_hook=rename_duplicates))

结果:

OrderedDict([('foo', 'bar'), ('foo1', 'qux'), ('troz', 'zort'), ('foo2', 'coconuts')])

推荐阅读