使用python向JSON添加重复键 [英] Adding duplicate keys to JSON with python
问题描述
有没有一种方法可以使用python向json添加重复密钥?
Is there a way to add duplicate keys to json with python?
据我了解,python词典中不能有重复的键.通常,创建json的方法是先创建字典,然后创建json.dumps
.但是,我需要在JSON中使用重复的键进行测试.但是我不能这样做,因为我不能在python字典中添加重复的键.我正在尝试在python 3中做到这一点
From my understanding, you can't have duplicate keys in python dictionaries. Usually, how I go about creating json is to create the dictionary and then json.dumps
. However, I need duplicated keys within the JSON for testing purposes. But I can't do so because I can't add duplicate keys in a python dictionary. I am trying to doing this in python 3
推荐答案
您总是可以手动构造这样的字符串值.
You could always construct such a string value by hand.
另一方面,可以使 C Python json
模块对重复的密钥进行编码.在 Python 2 中,这非常有点棘手,因为json
模块完全不遵循鸭嘴式输入.
On the other hand, one can make the CPython json
module to encode duplicate keys. This is very tricky in Python 2 because json
module does not respect duck-typing at all.
直接的解决方案是从collections.Mapping
继承-很好,因为"MyMapping
不是可序列化的JSON."
The straightforward solution would be to inherit from collections.Mapping
- well you can't, since "MyMapping
is not a JSON serializable."
下一个尝试将dict
子类化-很好,但是如果json.dumps
注意到类型为dict
,它将跳过调用__len__
并直接查看基础dict
-如果它为空,{}
是直接输出的,因此很明显,如果我们伪造方法,则基础字典一定不能为空.
Next one tries to subclass a dict
- well, but if json.dumps
notices that the type is dict
, it skips from calling __len__
, and sees the underlying dict
directly - if it is empty, {}
is output directly, so clearly if we fake the methods, the underlying dictionary must not be empty.
下一个欢乐源是实际上调用了__iter__
,它会迭代键;对于每个键,都会调用__getitem__
,因此我们需要记住给定键返回的对应值是什么...因此,我们得出了一个非常丑陋的Python 2解决方案:
The next source of joy is that actually __iter__
is called, which iterates keys; and for each key, the __getitem__
is called, so we need to remember what is the corresponding value to return for the given key... thus we arrive to a very ugly solution for Python 2:
import json
class FakeDict(dict):
def __init__(self, items):
# need to have something in the dictionary
self['something'] = 'something'
self.items = items
def __getitem__(self, key):
return self.last_val
def __iter__(self):
subiter = iter(self.items)
def generator():
for key, value in self.items:
self.last_val = value
yield key
return generator()
print json.dumps(FakeDict([('a', 5), ('a', 6)]), sort_keys=False)
在CPython 3.3+中,它稍微容易些...否,collections.abc.Mapping
不起作用,是的,您需要将dict
子类化,是的,您需要伪造您的字典包含内容...但是内部JSON编码器调用items
而不是__iter__
和__getitem__
!
In CPython 3.3+ it is slightly easier... no, collections.abc.Mapping
does not work, yes, you need to subclass a dict
, yes, you need to fake that your dictionary has content... but the internal JSON encoder calls items
instead of __iter__
and __getitem__
!
因此在Python 3上:
Thus on Python 3:
import json
class FakeDict(dict):
def __init__(self, items):
self['something'] = 'something'
self._items = items
def items(self):
return self._items
print(json.dumps(FakeDict([('a', 1), ('a', 2)])))
打印出
{"a": 1, "a": 2}
这篇关于使用python向JSON添加重复键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!