我发现当下面的代码运行时,python的json模块(从2.6开始就包含了)会将int字典的键转换成字符串。
>>> import json
>>> releases = {1: "foo-v0.1"}
>>> json.dumps(releases)
'{"1": "foo-v0.1"}'
有没有什么简单的方法可以将键保留为int,而不需要在转储和加载时解析字符串。我相信使用json模块提供的钩子是可能的,但同样这仍然需要解析。有没有可能我忽略了一个参数?
子问题:谢谢你的回答。看到json像我担心的那样工作,有没有一种简单的方法可以通过解析转储的输出来传递键类型?我还应该注意到,执行转储的代码和从服务器下载json对象并加载它的代码都是我写的。
9条答案
按热度按时间r7knjye21#
这是各种Map集合之间的细微差别之一,JSON将键视为字符串; Python支持不同的键,只是类型不同。
在Python中(显然在Lua中),Map(分别是字典或表)的键是对象引用。在Python中,它们必须是不可变类型,或者它们必须是实现
__hash__
方法的对象。(Lua文档建议它自动使用对象的ID作为哈希/键,甚至对于可变对象也是如此,并依赖于字符串实习来确保等价的字符串Map到相同的对象)。在Perl,Javascript,awk和许多其他语言中,散列,关联数组或任何给定语言中的键都是字符串(或Perl中的“标量”).在Perl中,
$foo{1}, $foo{1.0}, and $foo{"1"}
都是对%foo
中相同Map的引用--键被 * 评估 * 为标量!JSON最初是一种Javascript序列化技术。(JSON代表JavaS脚本ObjectN旋转。)自然,它实现了与其Map语义一致的Map表示法的语义。
如果序列化的两端都是Python,那么最好使用pickle。如果你真的需要将它们从JSON转换回原生Python对象,我想你有几个选择。首先,你可以尝试(
try: ... except: ...
),以便在字典查找失败的情况下将任何键转换为数字。如果你在另一端加上代码(这个JSON数据的序列化器或生成器),那么您可以让它对每个键值执行JSON序列化---将它们作为键列表提供。(然后,Python代码将首先遍历键列表,将它们示例化/反序列化为原生Python对象......然后使用它们访问Map之外的值)。ztigrdn82#
不,JavaScript中没有Number键,所有对象属性都转换为String。
这可能会导致一些看似奇怪的行为:
JavaScript对象并不是像Python这样的语言中所理解的那样真正正确的Map,使用非String的键会导致奇怪的结果,这就是为什么JSON总是显式地将键写为字符串,即使在看起来没有必要的地方。
k10s72fa3#
回答您的子问题:
它可以通过使用
json.loads(jsonDict, object_hook=jsonKeys2int)
来完成此函数也适用于嵌套字典,并使用字典解析。
如果您还想强制转换这些值,请使用:
它测试值的示例,并且仅当它们是字符串对象(确切地说是unicode)时才强制转换它们。
这两个函数都假定键(和值)为整数。
感谢:
How to use if/else in a dictionary comprehension?
Convert a string key to int in a Dictionary
7eumitmz4#
或者,您也可以尝试在使用json编码时将dictionary转换为[(k1,v1),(k2,v2)]格式的列表,并在解码后将其转换回dictionary。
我相信这将需要一些更多的工作,如有某种标志,以确定什么所有参数转换到字典后,解码从json回来。
siotufzp5#
我也遇到过同样的问题。正如其他人所指出的,在JSON中,Map键必须是字符串。你可以做两件事中的一件。你可以使用一个不太严格的JSON库,比如demjson,它允许整数字符串。如果没有其他程序(或者其他语言中没有其他人)会读它,那么你应该没问题。或者你可以使用不同的序列化语言。我不建议pickle。它很难读,而且是not designed to be secure。相反,我建议YAML。它(几乎)是JSON的超集,并且允许整数键(至少PyYAML允许)。
jv2fixgn6#
下面是我的解决方案!我使用了
object_hook
,当您嵌套json
时,它非常有用过滤器只用于将json键解析为int。您也可以将
int(v) if v.lstrip('-').isdigit() else v
过滤器用于json值。sg3maiej7#
使用
str(dict)
将字典转换为字符串,然后执行以下操作将其转换回dict:evrscar28#
我对Murmel的答案做了一个非常简单的扩展,我认为这将适用于一个相当任意的字典(包括嵌套字典),假设它可以被JSON首先转储。任何可以被解释为整数的键都将被转换为int。毫无疑问,这不是很有效,但它适用于我的目的,即存储到json字符串和从json字符串加载。
假设原始dict中的所有键都是整数,如果它们可以被强制转换为int,那么这将在存储为json后返回原始字典。
oxosxuxt9#
[NSFW]您可以自己编写
json.dumps
,下面是djson的示例:encoder.py。您可以这样使用它: