gpt4 book ai didi

python - 使用 Python >= 2.7 将嵌套的 namedtuple 序列化为 JSON

转载 作者:太空狗 更新时间:2023-10-29 20:20:21 25 4
gpt4 key购买 nike

我有一个类似于 CalvinKrishy's problem 的问题Samplebias 的解决方案不适用于我拥有的数据。

我正在使用 Python 2.7。

这是数据:

命名元组

>>> a_t = namedtuple('a','f1 words')
>>> word_t = namedtuple('word','f2 value')
>>> w1 = word_t(f2=[0,1,2], value='abc')
>>> w2 = word_t(f2=[3,4], value='def')
>>> a1 = a_t(f1=[0,1,2,3,4],words=[w1, w2])
>>> a1
a(f1=[0, 1, 2, 3, 4], words=[word(f2=[0, 1, 2], value='abc'), word(f2=[3, 4], value='def')])

字典

>>> w3 = {}
>>> w3['f2'] = [0,1,2]
>>> w3['value'] = 'abc'
>>> w4 = {}
>>> w4['f2'] = [3,4]
>>> w4['value'] = 'def'
>>> a2 = {}
>>> a2['f1'] = [0, 1, 2, 3, 4]
>>> a2['words'] = [w3,w4]
>>> a2
{'f1': [0, 1, 2, 3, 4], 'words': [{'f2': [0, 1, 2], 'value': 'abc'}, {'f2': [3, 4], 'value': 'def'}]}

如你所见,a1 和 a2 除了一个是 namedtuple 而另一个是 dict 之外都是一样的。

但是 json.dumps 是不同的:

>>> json.dumps(a1._asdict())
'{"f1": [0, 1, 2, 3, 4], "words": [[[0, 1, 2], "abc"], [[3, 4], "def"]]}'
>>> json.dumps(a2)
'{"f1": [0, 1, 2, 3, 4], "words": [{"f2": [0, 1, 2], "value": "abc"}, {"f2": [3, 4], "value": "def"}]}'

我希望 a1 的 json 格式与 a2 完全一样。

最佳答案

问题在于 namedtuple._asdict 的使用,而不是 json.dumps。如果您使用 namedtuple(..., verbose=True) 查看代码,您将看到:

def _asdict(self):
'Return a new OrderedDict which maps field names to their values'
return OrderedDict(zip(self._fields, self))

只有顶层实际上变成了OrderedDict,所有包含的元素都保持不变。这意味着嵌套的 namedtuple 仍然是 tuple 子类并且得到(正确)序列化等等。

如果您可以接受对特定转换函数的调用(例如对 _asdict 的调用),您可以编写自己的函数。

def namedtuple_asdict(obj):
if hasattr(obj, "_asdict"): # detect namedtuple
return OrderedDict(zip(obj._fields, (namedtuple_asdict(item) for item in obj)))
elif isinstance(obj, basestring): # iterables - strings
return obj
elif hasattr(obj, "keys"): # iterables - mapping
return OrderedDict(zip(obj.keys(), (namedtuple_asdict(item) for item in obj.values())))
elif hasattr(obj, "__iter__"): # iterables - sequence
return type(obj)((namedtuple_asdict(item) for item in obj))
else: # non-iterable cannot contain namedtuples
return obj

json.dumps(namedtuple_asdict(a1))
# prints '{"f1": [0, 1, 2, 3, 4], "words": [{"f2": [0, 1, 2], "value": "abc"}, {"f2": [3, 4], "value": "def"}]}'

如您所见,最大的问题是嵌套结构不是namedtuple但可以包含它们。

关于python - 使用 Python >= 2.7 将嵌套的 namedtuple 序列化为 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16938456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com