我发现当运行以下命令时,python的json模块(包含在2.6之后)将int字典键转换为字符串.
>>> import json >>> releases = {1: "foo-v0.1"} >>> json.dumps(releases) '{"1": "foo-v0.1"}'
有没有简单的方法将密钥保存为int,而无需在转储和加载时解析字符串.我相信可以使用json模块提供的钩子,但是这仍然需要解析.可能有一个我忽略的争论吗?干杯,chaz
子问题:谢谢你的回答.看到json像我担心的那样工作,是否有一种通过解析转储输出来传达密钥类型的简单方法?另外我应该注意执行转储的代码和从服务器下载json对象并加载它的代码都是由我编写的.
这是可以咬你的各种映射集合之间的微妙差异之一.
在Python中(显然在Lua中)映射的键(分别是字典或表)是对象引用.在Python中,它们必须是不可变类型,或者它们必须是实现__hash__
方法的对象.(Lua文档建议它自动使用对象的ID作为哈希/键,即使对于可变对象,也依赖于字符串实习以确保等效字符串映射到相同的对象).
在Perl,Javascript,awk和许多其他语言中,哈希,关联数组或它们为给定语言调用的任何键都是字符串(或Perl中的"标量").在perl $foo{1}, $foo{1.0}, and $foo{"1"}
中都是对相同映射的引用%foo
---键被评估为标量!
JSON最初是一个Javascript序列化技术.(JSON代表[J] ava [S] cript [o] bject [n] otation.)当然,它为其映射表示法实现语义,这与其映射语义一致.
如果序列化的两端都是Python,那么你最好使用泡菜.如果你真的需要将这些从JSON转换回本机Python对象,我猜你有几个选择.首先,您可以尝试(try: ... except: ...
)在字典查找失败的情况下将任何键转换为数字.或者,如果您将代码添加到另一端(此JSON数据的序列化程序或生成器),那么您可以让它对每个键值执行JSON序列化 - 将它们作为键列表提供.(然后你的Python代码首先遍历键列表,将它们实例化/反序列化为本机Python对象......然后使用它们来访问映射中的值).
不,JavaScript中没有数字键这样的东西.所有对象属性都转换为String.
var a= {1: 'a'}; for (k in a) alert(typeof k); // 'string'
这可能会导致一些看似奇怪的行为:
a[999999999999999999999]= 'a'; // this even works on Array alert(a[1000000000000000000000]); // 'a' alert(a['999999999999999999999']); // fail alert(a['1e+21']); // 'a'
JavaScript对象不是真正适当的映射,因为您在Python等语言中理解它,并且使用非String的键会导致奇怪.这就是为什么JSON总是明确地将键写为字符串,即使它看起来不必要.
或者,您也可以尝试将字典转换为[(k1,v1),(k2,v2)]格式列表,同时使用json对其进行编码,并在将其解码后将其转换回字典.
>>>> import json >>>> json.dumps(releases.items()) '[[1, "foo-v0.1"]]' >>>> releases = {1: "foo-v0.1"} >>>> releases == dict(json.loads(json.dumps(releases.items()))) True我相信这需要更多的工作,比如有一些标志来识别从json解码后要转换为字典的所有参数.
回答你的问题:
它可以通过使用来完成 json.loads(jsonDict, object_hook=jsonKeys2int)
def jsonKeys2int(x): if isinstance(x, dict): return {int(k):v for k,v in x.items()} return x
此函数也适用于嵌套dicts并使用dict理解.
如果您也想要转换值,请使用:
def jsonKV2int(x): if isinstance(x, dict): return {int(k):(int(v) if isinstance(v, unicode) else v) for k,v in x.items()} return x
它测试值的实例并仅在它们是字符串对象时才转换它们(确切地说是unicode).
两个函数都假定键(和值)是整数.
谢谢:
如何在词典理解中使用if/else?
在字典中将字符串键转换为int
我被同样的问题困扰了.正如其他人所指出的那样,在JSON中,映射键必须是字符串.你可以做两件事之一.您可以使用不太严格的JSON库,如demjson,它允许整数字符串.如果没有其他程序(或其他语言中没有其他程序)会读它,那么你应该没问题.或者您可以使用不同的序列化语言.我不会建议泡菜.它难以阅读,并且不是为了安全而设计的.相反,我建议YAML,它(几乎)是JSON的超集,并且允许整数键.(至少是PyYAML.)